LibreOffice Module sc (master)  1
tpsort.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #undef SC_DLLIMPLEMENTATION
21 
22 #include <vcl/svapp.hxx>
23 #include <vcl/weld.hxx>
25 #include <svtools/collatorres.hxx>
28 #include <osl/diagnose.h>
29 
30 #include <scitems.hxx>
31 #include <uiitems.hxx>
32 #include <viewdata.hxx>
33 #include <document.hxx>
34 #include <global.hxx>
35 #include <dbdata.hxx>
36 #include <userlist.hxx>
37 #include <rangeutl.hxx>
38 #include <scresid.hxx>
39 #include <sc.hrc>
40 #include <strings.hrc>
41 #include <globstr.hrc>
42 
43 #include <sortkeydlg.hxx>
44 
45 #include <sortdlg.hxx>
46 
47 #include <tpsort.hxx>
48 
49 using namespace com::sun::star;
50 
51 /*
52  * Since the settings on the second Tab Page (Options) effects
53  * the first Tab Page, there must be a way for it to communicate with the
54  * other Page.
55  *
56  * At the moment this problem is solved through using two data members of the
57  * Tab Pages. If a page is enabled / disabled, it compares this data member
58  * with its own state (-> Activate() / Deactivate()).
59  *
60  * In the meantime the class SfxTabPage offers the following method:
61  *
62  * virtual sal_Bool HasExchangeSupport() const; -> return sal_True;
63  * virtual void ActivatePage(const SfxItemSet &);
64  * virtual int DeactivatePage(SfxItemSet * = 0);
65  *
66  * This still needs to be changed!
67  */
68 
69 // Sort Criteria Tab page
70 
72  : SfxTabPage(pPage, pController, "modules/scalc/ui/sortcriteriapage.ui", "SortCriteriaPage", &rArgSet)
73  ,
74 
75  aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
76  aStrColumn ( ScResId( SCSTR_COLUMN ) ),
77  aStrRow ( ScResId( SCSTR_ROW ) ),
78 
79  nWhichSort ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
80  pViewData ( nullptr ),
81  aSortData ( static_cast<const ScSortItem&>(
82  rArgSet.Get( nWhichSort )).
83  GetSortData() ),
84  nFieldCount ( 0 ),
85  nSortKeyCount ( DEFSORT ),
86  bHasHeader ( false ),
87  bSortByRows ( false )
88 
89  , m_xScrolledWindow(m_xBuilder->weld_scrolled_window("SortCriteriaPage"))
90  , m_xBox(m_xBuilder->weld_container("SortKeyWindow"))
91  , m_aSortWin(m_xBox.get())
92 {
93  Init();
94 
95  m_aIdle.SetInvokeHandler(LINK(this, ScTabPageSortFields, ScrollToEndHdl));
96  m_aIdle.SetDebugName("ScTabPageSortFields Scroll To End Idle");
97 
99 }
100 
102 {
103  m_aSortWin.m_aSortKeyItems.clear();
104  m_xBox.reset();
105  m_xScrolledWindow.reset();
106 }
107 
109 {
110  const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
111  GetItemSet().Get( nWhichSort ));
112 
113  pViewData = rSortItem.GetViewData();
114  OSL_ENSURE( pViewData, "ViewData not found!" );
115 
116  nFieldArr.push_back( 0 );
117 
118  // Create three sort key dialogs by default
119  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
120  {
121  AddSortKey(i+1);
122  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed(LINK(this, ScTabPageSortFields, SelectHdl));
123  }
124 }
125 
126 std::unique_ptr<SfxTabPage> ScTabPageSortFields::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pArgSet)
127 {
128  return std::make_unique<ScTabPageSortFields>(pPage, pController, *pArgSet);
129 }
130 
131 void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
132 {
135 
136  if (m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->get_count() == 0)
137  FillFieldLists(0);
138 
139  // ListBox selection:
140  if (!aSortData.maKeyState.empty() && aSortData.maKeyState[0].bDoSort)
141  {
142  // Make sure that the all sort keys are reset
143  for ( sal_uInt16 i=nSortKeyCount; i<aSortData.GetSortKeyCount(); i++ )
144  {
145  AddSortKey(i+1);
146  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed( LINK( this,
147  ScTabPageSortFields, SelectHdl ) );
148  }
150  FillFieldLists(0);
151 
152  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
153  {
154  if (aSortData.maKeyState[i].bDoSort )
155  {
156  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active( GetFieldSelPos(
157  aSortData.maKeyState[i].nField ) );
158  (aSortData.maKeyState[i].bAscending)
159  ? m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true)
160  : m_aSortWin.m_aSortKeyItems[i]->m_xBtnDown->set_active(true);
161  }
162  else
163  {
164  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0); // Select none
165  m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
166  }
167  }
168 
169  // Enable or disable field depending on preceding Listbox selection
170  m_aSortWin.m_aSortKeyItems[0]->EnableField();
171  for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
172  if ( m_aSortWin.m_aSortKeyItems[i - 1]->m_xLbSort->get_active() == 0 )
173  m_aSortWin.m_aSortKeyItems[i]->DisableField();
174  else
175  m_aSortWin.m_aSortKeyItems[i]->EnableField();
176  }
177  else
178  {
179  SCCOL nCol = pViewData->GetCurX();
180 
181  if( nCol < aSortData.nCol1 )
182  nCol = aSortData.nCol1;
183  else if( nCol > aSortData.nCol2 )
184  nCol = aSortData.nCol2;
185 
186  sal_uInt16 nSort1Pos = nCol - aSortData.nCol1+1;
187 
188  m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->set_active(nSort1Pos);
189  for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
190  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0);
191 
192  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
193  m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
194 
195  m_aSortWin.m_aSortKeyItems[0]->EnableField();
196  m_aSortWin.m_aSortKeyItems[1]->EnableField();
197  for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
198  m_aSortWin.m_aSortKeyItems[i]->DisableField();
199  }
200 
201  if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
202  {
203  pDlg->SetByRows ( bSortByRows );
204  pDlg->SetHeaders( bHasHeader );
205  }
206 
207  // Make sure that there is always a last undefined sort key
208  if (m_aSortWin.m_aSortKeyItems[nSortKeyCount - 1]->m_xLbSort->get_active() > 0)
210 }
211 
213 {
214  ScSortParam aNewSortData = aSortData;
215 
216  const SfxItemSet* pExample = GetDialogExampleSet();
217  if (pExample)
218  {
219  const SfxPoolItem* pItem;
220  if (pExample->GetItemState(nWhichSort, true, &pItem) == SfxItemState::SET)
221  {
222  ScSortParam aTempData = static_cast<const ScSortItem*>(pItem)->GetSortData();
223  aTempData.maKeyState = aNewSortData.maKeyState;
224  aNewSortData = aTempData;
225  }
226  }
227  std::vector<sal_Int32> nSortPos;
228 
229  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
230  {
231  nSortPos.push_back(m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active());
232  if (nSortPos[i] == -1) nSortPos[i] = 0;
233  }
234 
235  if( nSortKeyCount >= aNewSortData.GetSortKeyCount() )
236  aNewSortData.maKeyState.resize(nSortKeyCount);
237 
238  if ( nSortPos[0] > 0 )
239  {
240  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
241  aNewSortData.maKeyState[i].bDoSort = (nSortPos[i] > 0);
242 
243  // If the "OK" was selected on the Options page while the sort
244  // direction was changed, then the first field (i.e. nFieldArr[0])
245  // of the respective direction is chosen as the sorting criterion:
246  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
247  if ( pDlg && bSortByRows != pDlg->GetByRows() )
248  {
249  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
250  aNewSortData.maKeyState[i].nField = 0;
251  }
252  else
253  {
254  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
255  aNewSortData.maKeyState[i].nField = nFieldArr[nSortPos[i]];
256  }
257 
258  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
259  aNewSortData.maKeyState[i].bAscending = m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->get_active();
260 
261  // bHasHeader is in ScTabPageSortOptions::FillItemSet, where it belongs
262  }
263  else
264  {
265  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
266  aNewSortData.maKeyState[i].bDoSort = false;
267  }
268 
269  rArgSet->Put( ScSortItem( SCITEM_SORTDATA, nullptr, &aNewSortData ) );
270 
271  return true;
272 }
273 
274 // for data exchange without dialogue detour:
276 {
277  // Refresh local copy with shared data
278  aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
279  if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
280  {
281  if ( bHasHeader != pDlg->GetHeaders()
282  || bSortByRows != pDlg->GetByRows() )
283  {
284  std::vector<sal_uInt16> nCurSel;
285  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
286  nCurSel.push_back( m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active() );
287 
288  bHasHeader = pDlg->GetHeaders();
289  bSortByRows = pDlg->GetByRows();
290  FillFieldLists(0);
291 
292  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
293  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(nCurSel[i]);
294  }
295  }
296 }
297 
299 {
300  if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
301  {
302  if ( bHasHeader != pDlg->GetHeaders() )
303  pDlg->SetHeaders( bHasHeader );
304 
305  if ( bSortByRows != pDlg->GetByRows() )
306  pDlg->SetByRows( bSortByRows );
307  }
308 
309  if ( pSetP )
310  FillItemSet( pSetP );
311 
312  return DeactivateRC::LeavePage;
313 }
314 
315 void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
316 {
317  if ( pViewData )
318  {
319  ScDocument* pDoc = pViewData->GetDocument();
320 
321  if ( pDoc )
322  {
323  for (sal_uInt16 j = nStartField; j < nSortKeyCount; ++j)
324  {
325  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->clear();
326  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->freeze();
327  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->append_text(aStrUndefined);
328  }
329 
330  SCCOL nFirstSortCol = aSortData.nCol1;
331  SCROW nFirstSortRow = aSortData.nRow1;
332  SCTAB nTab = pViewData->GetTabNo();
333  sal_uInt16 i = 1;
334  nFieldArr.clear();
335  nFieldArr.push_back(0);
336 
337  if ( bSortByRows )
338  {
339  OUString aFieldName;
340  SCCOL nMaxCol = pDoc->ClampToAllocatedColumns(nTab, aSortData.nCol2);
341  SCCOL col;
342 
343  for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
344  {
345  aFieldName = pDoc->GetString(col, nFirstSortRow, nTab);
346  if ( !bHasHeader || aFieldName.isEmpty() )
347  {
348  aFieldName = ScGlobal::ReplaceOrAppend( aStrColumn, "%1", ScColToAlpha( col ));
349  }
350  nFieldArr.push_back( col );
351 
352  for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
353  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
354 
355  i++;
356  }
357  }
358  else
359  {
360  OUString aFieldName;
361  SCROW nMaxRow = aSortData.nRow2;
362  SCROW row;
363 
364  for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS; row++ )
365  {
366  aFieldName = pDoc->GetString(nFirstSortCol, row, nTab);
367  if ( !bHasHeader || aFieldName.isEmpty() )
368  {
369  aFieldName = ScGlobal::ReplaceOrAppend( aStrRow, "%1", OUString::number( row+1));
370  }
371  nFieldArr.push_back( row );
372 
373  for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
374  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
375 
376  i++;
377  }
378  }
379 
380  for (sal_uInt16 j=nStartField; j < nSortKeyCount; ++j)
381  {
382  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->thaw();
383  }
384 
385  nFieldCount = i;
386  }
387  }
388 }
389 
391 {
392  sal_uInt16 nFieldPos = 0;
393  bool bFound = false;
394 
395  for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
396  {
397  if ( nFieldArr[n] == nField )
398  {
399  nFieldPos = n;
400  bFound = true;
401  }
402  }
403 
404  return nFieldPos;
405 }
406 
407 void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )
408 {
409  // Extend local SortParam copy
410  const ScSortKeyState atempKeyState = { 0, false, true };
411  aSortData.maKeyState.push_back( atempKeyState );
412 
413  // Add Sort Key Item
414  ++nSortKeyCount;
416  m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->connect_changed(
417  LINK( this, ScTabPageSortFields, SelectHdl ) );
418 
419  FillFieldLists( nItem );
420 
421  // Set Status
422  m_aSortWin.m_aSortKeyItems[nItem]->m_xBtnUp->set_active(true);
423  m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->set_active(0);
424 }
425 
426 // Handler:
427 
428 IMPL_LINK( ScTabPageSortFields, SelectHdl, weld::ComboBox&, rLb, void )
429 {
430  OUString aSelEntry = rLb.get_active_text();
431  ScSortKeyItems::iterator pIter;
432 
433  // If last listbox is enabled add one item
434  if (m_aSortWin.m_aSortKeyItems.back()->m_xLbSort.get() == &rLb)
435  {
436  if ( aSelEntry != aStrUndefined )
437  {
438  SetLastSortKey( nSortKeyCount );
439  return;
440  }
441  }
442 
443  // Find selected listbox
444  pIter = std::find_if(m_aSortWin.m_aSortKeyItems.begin(), m_aSortWin.m_aSortKeyItems.end(),
445  [&rLb](const ScSortKeyItems::value_type& rItem) { return rItem->m_xLbSort.get() == &rLb; });
446 
447  if (pIter == m_aSortWin.m_aSortKeyItems.end())
448  return;
449 
450  // If not selecting the last Listbox, modify the succeeding ones
451  ++pIter;
452  if ( std::distance(m_aSortWin.m_aSortKeyItems.begin(), pIter) < nSortKeyCount )
453  {
454  if ( aSelEntry == aStrUndefined )
455  {
456  for ( ; pIter != m_aSortWin.m_aSortKeyItems.end(); ++pIter )
457  {
458  (*pIter)->m_xLbSort->set_active(0);
459 
460  (*pIter)->DisableField();
461  }
462  }
463  else
464  {
465  (*pIter)->EnableField();
466  }
467  }
468 }
469 
470 IMPL_LINK_NOARG(ScTabPageSortFields, ScrollToEndHdl, Timer*, void)
471 {
472  m_xScrolledWindow->vadjustment_set_value(m_xScrolledWindow->vadjustment_get_upper());
473 }
474 
475 void ScTabPageSortFields::AddSortKey( sal_uInt16 nItem )
476 {
477  m_aSortWin.AddSortKey(nItem);
478  m_aIdle.Start();
479 }
480 
481 // Sort option Tab Page:
482 
484  : SfxTabPage(pPage, pController, "modules/scalc/ui/sortoptionspage.ui", "SortOptionsPage", &rArgSet)
485  , aStrRowLabel(ScResId(SCSTR_ROW_LABEL))
486  , aStrColLabel(ScResId(SCSTR_COL_LABEL))
487  , aStrUndefined(ScResId(SCSTR_UNDEFINED))
488  , nWhichSort(rArgSet.GetPool()->GetWhich(SID_SORT))
489  , aSortData(static_cast<const ScSortItem&>(rArgSet.Get(nWhichSort)).GetSortData())
490  , pViewData(nullptr)
491  , pDoc(nullptr)
492  , m_xBtnCase(m_xBuilder->weld_check_button("case"))
493  , m_xBtnHeader(m_xBuilder->weld_check_button("header"))
494  , m_xBtnFormats(m_xBuilder->weld_check_button("formats"))
495  , m_xBtnNaturalSort(m_xBuilder->weld_check_button("naturalsort"))
496  , m_xBtnCopyResult(m_xBuilder->weld_check_button("copyresult"))
497  , m_xLbOutPos(m_xBuilder->weld_combo_box("outarealb"))
498  , m_xEdOutPos(m_xBuilder->weld_entry("outareaed"))
499  , m_xBtnSortUser(m_xBuilder->weld_check_button("sortuser"))
500  , m_xLbSortUser(m_xBuilder->weld_combo_box("sortuserlb"))
501  , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
502  , m_xFtAlgorithm(m_xBuilder->weld_label("algorithmft"))
503  , m_xLbAlgorithm(m_xBuilder->weld_combo_box("algorithmlb"))
504  , m_xBtnTopDown(m_xBuilder->weld_radio_button("topdown"))
505  , m_xBtnLeftRight(m_xBuilder->weld_radio_button("leftright"))
506  , m_xBtnIncComments(m_xBuilder->weld_check_button("includenotes"))
507  , m_xBtnIncImages(m_xBuilder->weld_check_button("includeimages"))
508 {
509  m_xLbSortUser->set_size_request(m_xLbSortUser->get_approximate_digit_width() * 50, -1);
510  Init();
512 }
513 
515 {
516  // CollatorResource has user-visible names for sort algorithms
517  m_xColRes.reset(new CollatorResource);
518 
521 
522  const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
523  GetItemSet().Get( nWhichSort ));
524 
525  m_xLbOutPos->connect_changed( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
526  m_xBtnCopyResult->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
527  m_xBtnSortUser->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
528  m_xBtnTopDown->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
529  m_xBtnLeftRight->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
530  m_xLbLanguage->connect_changed( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
531 
532  pViewData = rSortItem.GetViewData();
533  pDoc = pViewData ? pViewData->GetDocument() : nullptr;
534 
535  OSL_ENSURE( pViewData, "ViewData not found! :-/" );
536 
537  if ( pViewData && pDoc )
538  {
539  ScDBCollection* pDBColl = pDoc->GetDBCollection();
540  const SCTAB nCurTab = pViewData->GetTabNo();
542 
543  m_xLbOutPos->clear();
544  m_xLbOutPos->append_text(aStrUndefined);
545  m_xLbOutPos->set_sensitive(false);
546 
547  ScAreaNameIterator aIter( pDoc );
548  OUString aName;
549  ScRange aRange;
550  while ( aIter.Next( aName, aRange ) )
551  {
552  OUString aRefStr(aRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDoc, eConv));
553  m_xLbOutPos->append(aRefStr, aName);
554  }
555 
556  m_xLbOutPos->set_active(0);
557  m_xEdOutPos->set_text(EMPTY_OUSTRING);
558 
559  // Check whether the field that is passed on is a database field:
560 
561  if ( pDBColl )
562  {
563  ScDBData* pDBData
564  = pDBColl->GetDBAtArea( nCurTab,
567  if ( pDBData )
568  {
569  m_xBtnHeader->set_active(pDBData->HasHeader());
570  }
571  }
572 
573  m_xBtnHeader->set_label(aStrColLabel);
574  }
575 
577 
578  // get available languages
579 
580  m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
581  m_xLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
582 }
583 
584 std::unique_ptr<SfxTabPage> ScTabPageSortOptions::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rArgSet)
585 {
586  return std::make_unique<ScTabPageSortOptions>(pPage, pController, *rArgSet);
587 }
588 
589 void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
590 {
591  if ( aSortData.bUserDef )
592  {
593  m_xBtnSortUser->set_active(true);
594  m_xLbSortUser->set_sensitive(true);
595  m_xLbSortUser->set_active(aSortData.nUserIndex);
596  }
597  else
598  {
599  m_xBtnSortUser->set_active(false);
600  m_xLbSortUser->set_sensitive(false);
601  m_xLbSortUser->set_active(0);
602  }
603 
604  m_xBtnCase->set_active( aSortData.bCaseSens );
605  m_xBtnFormats->set_active( aSortData.bIncludePattern );
606  m_xBtnHeader->set_active( aSortData.bHasHeader );
610 
611  if ( aSortData.bByRow )
612  {
613  m_xBtnTopDown->set_active(true);
614  m_xBtnHeader->set_label( aStrColLabel );
615  }
616  else
617  {
618  m_xBtnLeftRight->set_active(true);
619  m_xBtnHeader->set_label( aStrRowLabel );
620  }
621 
623  if ( eLang == LANGUAGE_DONTKNOW )
624  eLang = LANGUAGE_SYSTEM;
625  m_xLbLanguage->set_active_id(eLang);
626  FillAlgor(); // get algorithms, select default
627  if ( !aSortData.aCollatorAlgorithm.isEmpty() )
628  m_xLbAlgorithm->set_active_text(m_xColRes->GetTranslation(aSortData.aCollatorAlgorithm));
629 
630  if ( pDoc && !aSortData.bInplace )
631  {
635 
639 
640  OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
641  m_xBtnCopyResult->set_active(true);
642  m_xLbOutPos->set_sensitive(true);
643  m_xEdOutPos->set_sensitive(true);
644  m_xEdOutPos->set_text( aStr );
645  EdOutPosModHdl();
646  m_xEdOutPos->grab_focus();
647  m_xEdOutPos->select_region(0, -1);
648  }
649  else
650  {
651  m_xBtnCopyResult->set_active( false );
652  m_xLbOutPos->set_sensitive(false);
653  m_xEdOutPos->set_sensitive(false);
654  m_xEdOutPos->set_text( EMPTY_OUSTRING );
655  }
656 }
657 
659 {
660  // Create local copy of ScParam
661  ScSortParam aNewSortData = aSortData;
662 
663  const SfxItemSet* pExample = GetDialogExampleSet();
664  if (pExample)
665  {
666  const SfxPoolItem* pItem;
667  if (pExample->GetItemState(nWhichSort, true, &pItem) == SfxItemState::SET)
668  aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
669  }
670  aNewSortData.bByRow = m_xBtnTopDown->get_active();
671  aNewSortData.bHasHeader = m_xBtnHeader->get_active();
672  aNewSortData.bCaseSens = m_xBtnCase->get_active();
673  aNewSortData.bNaturalSort = m_xBtnNaturalSort->get_active();
674  aNewSortData.bIncludeComments= m_xBtnIncComments->get_active();
675  aNewSortData.bIncludeGraphicObjects = m_xBtnIncImages->get_active();
676  aNewSortData.bIncludePattern = m_xBtnFormats->get_active();
677  aNewSortData.bInplace = !m_xBtnCopyResult->get_active();
678  aNewSortData.nDestCol = theOutPos.Col();
679  aNewSortData.nDestRow = theOutPos.Row();
680  aNewSortData.nDestTab = theOutPos.Tab();
681  aNewSortData.bUserDef = m_xBtnSortUser->get_active();
682  aNewSortData.nUserIndex = (m_xBtnSortUser->get_active())
683  ? m_xLbSortUser->get_active()
684  : 0;
685 
686  // get locale
687  LanguageType eLang = m_xLbLanguage->get_active_id();
688  aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);
689 
690  // get algorithm
691  OUString sAlg;
692  if ( eLang != LANGUAGE_SYSTEM )
693  {
694  uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms(
695  aNewSortData.aCollatorLocale );
696  const int nSel = m_xLbAlgorithm->get_active();
697  if ( nSel < aAlgos.getLength() )
698  sAlg = aAlgos[nSel];
699  }
700  aNewSortData.aCollatorAlgorithm = sAlg;
701 
702  rArgSet->Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
703 
704  return true;
705 }
706 
707 // for data exchange without dialogue detour:
709 {
710  // Refresh local copy with shared data
711  aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
712  if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
713  {
714  if ( m_xBtnHeader->get_active() != pDlg->GetHeaders() )
715  {
716  m_xBtnHeader->set_active( pDlg->GetHeaders() );
717  }
718 
719  if ( m_xBtnTopDown->get_active() != pDlg->GetByRows() )
720  {
721  m_xBtnTopDown->set_active( pDlg->GetByRows() );
722  m_xBtnLeftRight->set_active( !pDlg->GetByRows() );
723  }
724 
725  m_xBtnHeader->set_label( (pDlg->GetByRows())
726  ? aStrColLabel
727  : aStrRowLabel );
728  }
729 }
730 
732 {
733  bool bPosInputOk = true;
734 
735  if ( m_xBtnCopyResult->get_active() )
736  {
737  OUString thePosStr = m_xEdOutPos->get_text();
738  ScAddress thePos;
739  sal_Int32 nColonPos = thePosStr.indexOf( ':' );
740 
741  if ( -1 != nColonPos )
742  thePosStr = thePosStr.copy( 0, nColonPos );
743 
744  if ( pViewData )
745  {
746  // visible table is default for input without table
747  // must be changed to GetRefTabNo when sorting has RefInput!
748  thePos.SetTab( pViewData->GetTabNo() );
749  }
750 
751  ScRefFlags nResult = thePos.Parse( thePosStr, pDoc, pDoc->GetAddressConvention() );
752 
753  bPosInputOk = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID;
754 
755  if ( !bPosInputOk )
756  {
757  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
758  VclMessageType::Warning, VclButtonsType::Ok,
759  ScResId(STR_INVALID_TABREF)));
760  xBox->run();
761  m_xEdOutPos->grab_focus();
762  m_xEdOutPos->select_region(0, -1);
763  theOutPos.Set(0,0,0);
764  }
765  else
766  {
767  m_xEdOutPos->set_text(thePosStr);
768  theOutPos = thePos;
769  }
770  }
771 
772  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
773  if (pDlg && bPosInputOk)
774  {
775  pDlg->SetHeaders( m_xBtnHeader->get_active() );
776  pDlg->SetByRows ( m_xBtnTopDown->get_active() );
777  }
778 
779  if ( pSetP && bPosInputOk )
780  FillItemSet( pSetP );
781 
782  return bPosInputOk ? DeactivateRC::LeavePage : DeactivateRC::KeepPage;
783 }
784 
786 {
787  ScUserList* pUserLists = ScGlobal::GetUserList();
788 
789  m_xLbSortUser->clear();
790  if ( pUserLists )
791  {
792  size_t nCount = pUserLists->size();
793  for (size_t i=0; i<nCount; ++i)
794  m_xLbSortUser->append_text((*pUserLists)[i].GetString());
795  }
796 }
797 
798 // Handler:
799 
800 IMPL_LINK( ScTabPageSortOptions, EnableHdl, weld::ToggleButton&, rButton, void )
801 {
802  if (&rButton == m_xBtnCopyResult.get())
803  {
804  if (rButton.get_active())
805  {
806  m_xLbOutPos->set_sensitive(true);
807  m_xEdOutPos->set_sensitive(true);
808  m_xEdOutPos->grab_focus();
809  }
810  else
811  {
812  m_xLbOutPos->set_sensitive(false);
813  m_xEdOutPos->set_sensitive(false);
814  }
815  }
816  else if (&rButton == m_xBtnSortUser.get())
817  {
818  if (rButton.get_active())
819  {
820  m_xLbSortUser->set_sensitive(true);
821  m_xLbSortUser->grab_focus();
822  }
823  else
824  m_xLbSortUser->set_sensitive(false);
825  }
826 }
827 
828 IMPL_LINK(ScTabPageSortOptions, SelOutPosHdl, weld::ComboBox&, rLb, void)
829 {
830  if (&rLb == m_xLbOutPos.get())
831  {
832  OUString aString;
833  const int nSelPos = m_xLbOutPos->get_active();
834 
835  if (nSelPos > 0)
836  aString = m_xLbOutPos->get_id(nSelPos);
837 
838  m_xEdOutPos->set_text(aString);
839  }
840 }
841 
843 {
844  if (m_xBtnTopDown->get_active())
845  m_xBtnHeader->set_label(aStrColLabel);
846  else
847  m_xBtnHeader->set_label(aStrRowLabel);
848 }
849 
851 {
852  OUString theCurPosStr = m_xEdOutPos->get_text();
853  ScRefFlags nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
854 
855  if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
856  {
857  bool bFound = false;
858  sal_Int32 i = 0;
859  const int nCount = m_xLbOutPos->get_count();
860 
861  for ( i=2; i<nCount && !bFound; i++ )
862  {
863  OUString aStr = m_xLbOutPos->get_id(i);
864  bFound = (theCurPosStr == aStr);
865  }
866 
867  if ( bFound )
868  m_xLbOutPos->set_active(--i);
869  else
870  m_xLbOutPos->set_active(0);
871  }
872 }
873 
875 {
876  m_xLbAlgorithm->freeze();
877  m_xLbAlgorithm->clear();
878 
879  LanguageType eLang = m_xLbLanguage->get_active_id();
880  if ( eLang == LANGUAGE_SYSTEM )
881  {
882  // for LANGUAGE_SYSTEM no algorithm can be selected because
883  // it wouldn't necessarily exist for other languages
884  // -> leave list box empty if LANGUAGE_SYSTEM is selected
885  m_xFtAlgorithm->set_sensitive( false ); // nothing to select
886  m_xLbAlgorithm->set_sensitive( false ); // nothing to select
887  }
888  else
889  {
890  lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
891  const uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms( aLocale );
892 
893  long nCount = aAlgos.getLength();
894  for (const OUString& sAlg : aAlgos)
895  {
896  OUString sUser = m_xColRes->GetTranslation( sAlg );
897  m_xLbAlgorithm->append_text(sUser);
898  }
899  m_xLbAlgorithm->set_active(0); // first entry is default
900  m_xFtAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
901  m_xLbAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
902  }
903 
904  m_xLbAlgorithm->thaw();
905 }
906 
908 {
909  FillAlgor();
910 }
911 
912 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool Next(OUString &rName, ScRange &rRange)
Definition: rangeutl.cxx:949
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
::std::vector< ScSortKeyState > maKeyState
Definition: sortparam.hxx:61
sal_uInt16 nUserIndex
Definition: sortparam.hxx:47
SCROW nRow1
Definition: sortparam.hxx:44
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2111
Collection of user-defined sort lists.
Definition: userlist.hxx:66
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:816
std::unique_ptr< weld::ComboBox > m_xLbAlgorithm
Definition: tpsort.hxx:133
ScAddress aStart
Definition: address.hxx:500
ScViewData * GetViewData() const
Definition: uiitems.hxx:141
IMPL_LINK(ScTabPageSortFields, SelectHdl, weld::ComboBox &, rLb, void)
Definition: tpsort.cxx:428
std::unique_ptr< weld::CheckButton > m_xBtnSortUser
Definition: tpsort.hxx:129
#define EMPTY_OUSTRING
Definition: global.hxx:214
SCCOL nCol2
Definition: sortparam.hxx:45
SCROW Row() const
Definition: address.hxx:262
std::unique_ptr< SvxLanguageBox > m_xLbLanguage
Definition: tpsort.hxx:131
std::unique_ptr< weld::Entry > m_xEdOutPos
Definition: tpsort.hxx:128
virtual bool FillItemSet(SfxItemSet *rArgSet) override
Definition: tpsort.cxx:658
OUString aStrUndefined
Definition: tpsort.hxx:60
css::lang::Locale aCollatorLocale
Definition: sortparam.hxx:62
SCCOL nDestCol
Definition: sortparam.hxx:58
bool HasHeader() const
Definition: dbdata.hxx:130
bool bIncludeComments
Definition: sortparam.hxx:52
std::unique_ptr< weld::ComboBox > m_xLbOutPos
Definition: tpsort.hxx:127
OUString aStrUndefined
Definition: tpsort.hxx:111
ScViewData * pViewData
Definition: tpsort.hxx:115
ScTabPageSortOptions(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rArgSet)
Definition: tpsort.cxx:483
static LanguageType convertToLanguageType(const css::lang::Locale &rLocale, bool bResolveSystem=true)
ScSortParam aSortData
Definition: tpsort.hxx:114
sal_Int64 n
void ScColToAlpha(OUStringBuffer &rBuf, SCCOL nCol)
append alpha representation of column to buffer
Definition: address.cxx:1921
sal_uInt16 GetFieldSelPos(SCCOLROW nField)
Definition: tpsort.cxx:390
virtual void ActivatePage(const SfxItemSet &rSet) override
Definition: tpsort.cxx:275
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
size_t size() const
Definition: userlist.cxx:345
static SC_DLLPUBLIC OUString ReplaceOrAppend(const OUString &rString, const OUString &rPlaceholder, const OUString &rReplacement)
Replaces the first occurrence of rPlaceholder in rString with rReplacement, or if rPlaceholder is not...
Definition: global.cxx:1075
std::unique_ptr< weld::RadioButton > m_xBtnLeftRight
Definition: tpsort.hxx:135
OUString aStrRow
Definition: tpsort.hxx:62
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: tpsort.cxx:731
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:475
std::unique_ptr< weld::CheckButton > m_xBtnHeader
Definition: tpsort.hxx:123
ScAddress theOutPos
Definition: tpsort.hxx:117
bool bUserDef
Definition: sortparam.hxx:54
ScSortParam aSortData
Definition: tpsort.hxx:66
SCROW nRow2
Definition: sortparam.hxx:46
std::unique_ptr< weld::CheckButton > m_xBtnNaturalSort
Definition: tpsort.hxx:125
void SetLastSortKey(sal_uInt16 nItem)
Definition: tpsort.cxx:407
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
bool bNaturalSort
Definition: sortparam.hxx:51
void SetExchangeSupport()
int nCount
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3489
virtual void Start() override
SCTAB Tab() const
Definition: address.hxx:271
ScDocument * GetDocument() const
Definition: viewdata.cxx:859
std::unique_ptr< weld::CheckButton > m_xBtnCopyResult
Definition: tpsort.hxx:126
ScViewData * pViewData
Definition: tpsort.hxx:65
bool bIncludeGraphicObjects
Definition: sortparam.hxx:53
std::unique_ptr< weld::CheckButton > m_xBtnIncComments
Definition: tpsort.hxx:136
const ScDBData * GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
Definition: dbdata.cxx:1344
const SfxItemSet & GetItemSet() const
SCCOL nCol1
Definition: sortparam.hxx:43
void SetDebugName(const char *pDebugName)
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: tpsort.cxx:298
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
virtual ~ScTabPageSortFields() override
Definition: tpsort.cxx:101
#define SCITEM_SORTDATA
Definition: scitems.hxx:90
std::unique_ptr< weld::ComboBox > m_xLbSortUser
Definition: tpsort.hxx:130
std::unique_ptr< weld::ScrolledWindow > m_xScrolledWindow
Definition: tpsort.hxx:74
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
sal_uInt16 nSortKeyCount
Definition: tpsort.hxx:69
int i
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:406
#define LANGUAGE_SYSTEM
sal_Int16 SCCOL
Definition: types.hxx:22
std::unique_ptr< weld::Container > m_xBox
Definition: tpsort.hxx:75
ScSortKeyWindow m_aSortWin
Definition: tpsort.hxx:76
void FillUserSortListBox()
Definition: tpsort.cxx:785
SC_DLLPUBLIC SCCOL ClampToAllocatedColumns(SCTAB nTab, SCCOL nCol) const
Definition: documen3.cxx:2105
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
static SC_DLLPUBLIC ScUserList * GetUserList()
Definition: global.cxx:277
#define LANGUAGE_DONTKNOW
virtual bool FillItemSet(SfxItemSet *rArgSet) override
Definition: tpsort.cxx:212
void FillFieldLists(sal_uInt16 nStartField)
Definition: tpsort.cxx:315
const sal_uInt16 nWhichSort
Definition: tpsort.hxx:64
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rArgSet)
Definition: tpsort.cxx:126
bool bCaseSens
Definition: sortparam.hxx:50
OUString aStrColumn
Definition: tpsort.hxx:61
void AddSortKey(sal_uInt16 nItem)
Definition: sortkeydlg.cxx:42
ScSortKeyItems m_aSortKeyItems
Definition: sortkeydlg.hxx:38
#define SC_MAXFIELDS
Definition: tpsort.hxx:37
std::unique_ptr< weld::RadioButton > m_xBtnTopDown
Definition: tpsort.hxx:134
const SfxItemSet * GetDialogExampleSet() const
SCCOL Col() const
Definition: address.hxx:267
std::unique_ptr< CollatorWrapper > m_xColWrap
Definition: tpsort.hxx:120
virtual void ActivatePage(const SfxItemSet &rSet) override
Definition: tpsort.cxx:708
sal_uInt16 nFieldCount
Definition: tpsort.hxx:68
void AddSortKey(sal_uInt16 nItem)
Definition: tpsort.cxx:475
std::unique_ptr< weld::CheckButton > m_xBtnIncImages
Definition: tpsort.hxx:137
std::unique_ptr< weld::CheckButton > m_xBtnFormats
Definition: tpsort.hxx:124
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:18
std::unique_ptr< CollatorResource > m_xColRes
Definition: tpsort.hxx:119
weld::Window * GetFrameWeld() const
bool bInplace
Definition: sortparam.hxx:56
bool bHasHeader
Definition: sortparam.hxx:48
virtual void Reset(const SfxItemSet *rArgSet) override
Definition: tpsort.cxx:589
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
#define GetWhich(nSlot)
std::unique_ptr< weld::Label > m_xFtAlgorithm
Definition: tpsort.hxx:132
IMPL_LINK_NOARG(ScTabPageSortFields, ScrollToEndHdl, Timer *, void)
Definition: tpsort.cxx:470
virtual void Reset(const SfxItemSet *rArgSet) override
Definition: tpsort.cxx:131
sal_uInt16 GetSortKeyCount() const
Definition: sortparam.hxx:79
OUString aName
void SetByRows(bool bByRows)
Definition: sortdlg.hxx:32
Reference< XComponentContext > getProcessComponentContext()
SfxOkDialogController * GetDialogController() const
void SetInvokeHandler(const Link< Timer *, void > &rLink)
const sal_uInt16 nWhichSort
Definition: tpsort.hxx:113
OUString aCollatorAlgorithm
Definition: sortparam.hxx:63
OUString aStrColLabel
Definition: tpsort.hxx:110
std::vector< SCCOLROW > nFieldArr
Definition: tpsort.hxx:67
ScTabPageSortFields(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rArgSet)
Definition: tpsort.cxx:71
DeactivateRC
void SetHeaders(bool bHeaders)
Definition: sortdlg.hxx:31
SCROW nDestRow
Definition: sortparam.hxx:59
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
std::unique_ptr< weld::CheckButton > m_xBtnCase
Definition: tpsort.hxx:122
ScRefFlags
Definition: address.hxx:145
bool bIncludePattern
Definition: sortparam.hxx:55
bool GetByRows() const
Definition: sortdlg.hxx:34
#define DEFSORT
Definition: sortparam.hxx:23
OUString aStrRowLabel
Definition: tpsort.hxx:109
ScDocument * pDoc
Definition: tpsort.hxx:116
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument *=nullptr, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1543
aStr
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
sal_Int16 SCTAB
Definition: types.hxx:23
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *pArgSet)
Definition: tpsort.cxx:584
SCCOL GetCurX() const
Definition: viewdata.hxx:401
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
SCTAB nDestTab
Definition: sortparam.hxx:57