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  // show actual size of the sorting keys without limiting them to the default size
86  nSortKeyCount(std::max(aSortData.GetSortKeyCount(), static_cast<sal_uInt16>(DEFSORT))),
87  bHasHeader ( false ),
88  bSortByRows ( false )
89 
90  , m_xScrolledWindow(m_xBuilder->weld_scrolled_window("SortCriteriaPage"))
91  , m_xBox(m_xBuilder->weld_container("SortKeyWindow"))
92  , m_aSortWin(m_xBox.get())
93 {
94  Init();
95 
96  m_aIdle.SetInvokeHandler(LINK(this, ScTabPageSortFields, ScrollToEndHdl));
97  m_aIdle.SetDebugName("ScTabPageSortFields Scroll To End Idle");
98 
100 }
101 
103 {
104  m_aSortWin.m_aSortKeyItems.clear();
105  m_xBox.reset();
106  m_xScrolledWindow.reset();
107 }
108 
110 {
111  const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
112  GetItemSet().Get( nWhichSort ));
113 
114  pViewData = rSortItem.GetViewData();
115  OSL_ENSURE( pViewData, "ViewData not found!" );
116 
117  nFieldArr.push_back( 0 );
118 
119  // Create three sort key dialogs by default
120  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
121  {
122  AddSortKey(i+1);
123  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed(LINK(this, ScTabPageSortFields, SelectHdl));
124  }
125 }
126 
127 std::unique_ptr<SfxTabPage> ScTabPageSortFields::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pArgSet)
128 {
129  return std::make_unique<ScTabPageSortFields>(pPage, pController, *pArgSet);
130 }
131 
132 void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
133 {
136 
137  if (m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->get_count() == 0)
138  FillFieldLists(0);
139 
140  // ListBox selection:
141  if (!aSortData.maKeyState.empty() && aSortData.maKeyState[0].bDoSort)
142  {
143  // Make sure that the all sort keys are reset
144  for ( sal_uInt16 i=nSortKeyCount; i<aSortData.GetSortKeyCount(); i++ )
145  {
146  AddSortKey(i+1);
147  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed( LINK( this,
148  ScTabPageSortFields, SelectHdl ) );
149  }
151  FillFieldLists(0);
152 
153  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
154  {
155  if (aSortData.maKeyState[i].bDoSort )
156  {
157  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active( GetFieldSelPos(
158  aSortData.maKeyState[i].nField ) );
159  (aSortData.maKeyState[i].bAscending)
160  ? m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true)
161  : m_aSortWin.m_aSortKeyItems[i]->m_xBtnDown->set_active(true);
162  }
163  else
164  {
165  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0); // Select none
166  m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
167  }
168  }
169 
170  // Enable or disable field depending on preceding Listbox selection
171  m_aSortWin.m_aSortKeyItems[0]->EnableField();
172  for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
173  if ( m_aSortWin.m_aSortKeyItems[i - 1]->m_xLbSort->get_active() == 0 )
174  m_aSortWin.m_aSortKeyItems[i]->DisableField();
175  else
176  m_aSortWin.m_aSortKeyItems[i]->EnableField();
177  }
178  else
179  {
180  SCCOL nCol = pViewData->GetCurX();
181 
182  if( nCol < aSortData.nCol1 )
183  nCol = aSortData.nCol1;
184  else if( nCol > aSortData.nCol2 )
185  nCol = aSortData.nCol2;
186 
187  sal_uInt16 nSort1Pos = nCol - aSortData.nCol1+1;
188 
189  m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->set_active(nSort1Pos);
190  for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
191  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0);
192 
193  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
194  m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
195 
196  m_aSortWin.m_aSortKeyItems[0]->EnableField();
197  m_aSortWin.m_aSortKeyItems[1]->EnableField();
198  for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
199  m_aSortWin.m_aSortKeyItems[i]->DisableField();
200  }
201 
202  if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
203  {
204  pDlg->SetByRows ( bSortByRows );
205  pDlg->SetHeaders( bHasHeader );
206  }
207 
208  // Make sure that there is always a last undefined sort key
209  if (m_aSortWin.m_aSortKeyItems[nSortKeyCount - 1]->m_xLbSort->get_active() > 0)
211 }
212 
214 {
215  ScSortParam aNewSortData = aSortData;
216 
217  const SfxItemSet* pExample = GetDialogExampleSet();
218  if (pExample)
219  {
220  const SfxPoolItem* pItem;
221  if (pExample->GetItemState(nWhichSort, true, &pItem) == SfxItemState::SET)
222  {
223  ScSortParam aTempData = static_cast<const ScSortItem*>(pItem)->GetSortData();
224  aTempData.maKeyState = aNewSortData.maKeyState;
225  aNewSortData = aTempData;
226  }
227  }
228  std::vector<sal_Int32> nSortPos;
229 
230  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
231  {
232  nSortPos.push_back(m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active());
233  if (nSortPos[i] == -1) nSortPos[i] = 0;
234  }
235 
236  if( nSortKeyCount >= aNewSortData.GetSortKeyCount() )
237  aNewSortData.maKeyState.resize(nSortKeyCount);
238 
239  if ( nSortPos[0] > 0 )
240  {
241  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
242  aNewSortData.maKeyState[i].bDoSort = (nSortPos[i] > 0);
243 
244  // If the "OK" was selected on the Options page while the sort
245  // direction was changed, then the first field (i.e. nFieldArr[0])
246  // of the respective direction is chosen as the sorting criterion:
247  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
248  if ( pDlg && bSortByRows != pDlg->GetByRows() )
249  {
250  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
251  aNewSortData.maKeyState[i].nField = 0;
252  }
253  else
254  {
255  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
256  aNewSortData.maKeyState[i].nField = nFieldArr[nSortPos[i]];
257  }
258 
259  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
260  aNewSortData.maKeyState[i].bAscending = m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->get_active();
261 
262  // bHasHeader is in ScTabPageSortOptions::FillItemSet, where it belongs
263  }
264  else
265  {
266  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
267  aNewSortData.maKeyState[i].bDoSort = false;
268  }
269 
270  rArgSet->Put( ScSortItem( SCITEM_SORTDATA, nullptr, &aNewSortData ) );
271 
272  return true;
273 }
274 
275 // for data exchange without dialogue detour:
277 {
278  // Refresh local copy with shared data
279  aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
280  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
281  if (!pDlg)
282  return;
283 
284  if ( bHasHeader == pDlg->GetHeaders() && bSortByRows == pDlg->GetByRows() )
285  return;
286 
287  std::vector<sal_uInt16> nCurSel;
288  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
289  nCurSel.push_back( m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active() );
290 
291  bHasHeader = pDlg->GetHeaders();
292  bSortByRows = pDlg->GetByRows();
293  FillFieldLists(0);
294 
295  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
296  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(nCurSel[i]);
297 }
298 
300 {
301  if (ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController()))
302  {
303  if ( bHasHeader != pDlg->GetHeaders() )
304  pDlg->SetHeaders( bHasHeader );
305 
306  if ( bSortByRows != pDlg->GetByRows() )
307  pDlg->SetByRows( bSortByRows );
308  }
309 
310  if ( pSetP )
311  FillItemSet( pSetP );
312 
313  return DeactivateRC::LeavePage;
314 }
315 
316 void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
317 {
318  if ( !pViewData )
319  return;
320 
321  ScDocument& rDoc = pViewData->GetDocument();
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 = rDoc.ClampToAllocatedColumns(nTab, aSortData.nCol2);
341  SCCOL col;
342 
343  for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS(rDoc.GetSheetLimits()); col++ )
344  {
345  aFieldName = rDoc.GetString(col, nFirstSortRow, nTab);
346  if ( !bHasHeader || aFieldName.isEmpty() )
347  {
348  aFieldName = ScGlobal::ReplaceOrAppend( aStrColumn, u"%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(rDoc.GetSheetLimits()); row++ )
365  {
366  aFieldName = rDoc.GetString(nFirstSortCol, row, nTab);
367  if ( !bHasHeader || aFieldName.isEmpty() )
368  {
369  aFieldName = ScGlobal::ReplaceOrAppend( aStrRow, u"%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 
389 {
390  sal_uInt16 nFieldPos = 0;
391  bool bFound = false;
392 
393  for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
394  {
395  if ( nFieldArr[n] == nField )
396  {
397  nFieldPos = n;
398  bFound = true;
399  }
400  }
401 
402  return nFieldPos;
403 }
404 
405 void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )
406 {
407  // Extend local SortParam copy
408  const ScSortKeyState atempKeyState = { 0, false, true };
409  aSortData.maKeyState.push_back( atempKeyState );
410 
411  // Add Sort Key Item
412  ++nSortKeyCount;
414  m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->connect_changed(
415  LINK( this, ScTabPageSortFields, SelectHdl ) );
416 
417  FillFieldLists( nItem );
418 
419  // Set Status
420  m_aSortWin.m_aSortKeyItems[nItem]->m_xBtnUp->set_active(true);
421  m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->set_active(0);
422 }
423 
424 // Handler:
425 
426 IMPL_LINK( ScTabPageSortFields, SelectHdl, weld::ComboBox&, rLb, void )
427 {
428  OUString aSelEntry = rLb.get_active_text();
429  ScSortKeyItems::iterator pIter;
430 
431  // If last listbox is enabled add one item
432  if (m_aSortWin.m_aSortKeyItems.back()->m_xLbSort.get() == &rLb)
433  {
434  if ( aSelEntry != aStrUndefined )
435  {
436  SetLastSortKey( nSortKeyCount );
437  return;
438  }
439  }
440 
441  // Find selected listbox
442  pIter = std::find_if(m_aSortWin.m_aSortKeyItems.begin(), m_aSortWin.m_aSortKeyItems.end(),
443  [&rLb](const ScSortKeyItems::value_type& rItem) { return rItem->m_xLbSort.get() == &rLb; });
444 
445  if (pIter == m_aSortWin.m_aSortKeyItems.end())
446  return;
447 
448  // If not selecting the last Listbox, modify the succeeding ones
449  ++pIter;
450  if ( std::distance(m_aSortWin.m_aSortKeyItems.begin(), pIter) >= nSortKeyCount )
451  return;
452 
453  if ( aSelEntry == aStrUndefined )
454  {
455  for ( ; pIter != m_aSortWin.m_aSortKeyItems.end(); ++pIter )
456  {
457  (*pIter)->m_xLbSort->set_active(0);
458 
459  (*pIter)->DisableField();
460  }
461  }
462  else
463  {
464  (*pIter)->EnableField();
465  }
466 }
467 
468 IMPL_LINK_NOARG(ScTabPageSortFields, ScrollToEndHdl, Timer*, void)
469 {
470  m_xScrolledWindow->vadjustment_set_value(m_xScrolledWindow->vadjustment_get_upper());
471 }
472 
473 void ScTabPageSortFields::AddSortKey( sal_uInt16 nItem )
474 {
475  m_aSortWin.AddSortKey(nItem);
476  m_aIdle.Start();
477 }
478 
479 // Sort option Tab Page:
480 
482  : SfxTabPage(pPage, pController, "modules/scalc/ui/sortoptionspage.ui", "SortOptionsPage", &rArgSet)
483  , aStrRowLabel(ScResId(SCSTR_ROW_LABEL))
484  , aStrColLabel(ScResId(SCSTR_COL_LABEL))
485  , aStrUndefined(ScResId(SCSTR_UNDEFINED))
486  , nWhichSort(rArgSet.GetPool()->GetWhich(SID_SORT))
487  , aSortData(static_cast<const ScSortItem&>(rArgSet.Get(nWhichSort)).GetSortData())
488  , pViewData(nullptr)
489  , pDoc(nullptr)
490  , m_xBtnCase(m_xBuilder->weld_check_button("case"))
491  , m_xBtnHeader(m_xBuilder->weld_check_button("header"))
492  , m_xBtnFormats(m_xBuilder->weld_check_button("formats"))
493  , m_xBtnNaturalSort(m_xBuilder->weld_check_button("naturalsort"))
494  , m_xBtnCopyResult(m_xBuilder->weld_check_button("copyresult"))
495  , m_xLbOutPos(m_xBuilder->weld_combo_box("outarealb"))
496  , m_xEdOutPos(m_xBuilder->weld_entry("outareaed"))
497  , m_xBtnSortUser(m_xBuilder->weld_check_button("sortuser"))
498  , m_xLbSortUser(m_xBuilder->weld_combo_box("sortuserlb"))
499  , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
500  , m_xFtAlgorithm(m_xBuilder->weld_label("algorithmft"))
501  , m_xLbAlgorithm(m_xBuilder->weld_combo_box("algorithmlb"))
502  , m_xBtnTopDown(m_xBuilder->weld_radio_button("topdown"))
503  , m_xBtnLeftRight(m_xBuilder->weld_radio_button("leftright"))
504  , m_xBtnIncComments(m_xBuilder->weld_check_button("includenotes"))
505  , m_xBtnIncImages(m_xBuilder->weld_check_button("includeimages"))
506 {
507  m_xLbSortUser->set_size_request(m_xLbSortUser->get_approximate_digit_width() * 50, -1);
508  Init();
510 }
511 
513 {
514  // CollatorResource has user-visible names for sort algorithms
515  m_xColRes.reset(new CollatorResource);
516 
519 
520  const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
521  GetItemSet().Get( nWhichSort ));
522 
523  m_xLbOutPos->connect_changed( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
524  m_xBtnCopyResult->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
525  m_xBtnSortUser->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
526  m_xBtnTopDown->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
527  m_xBtnLeftRight->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
528  m_xLbLanguage->connect_changed( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
529 
530  pViewData = rSortItem.GetViewData();
531  pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
532 
533  OSL_ENSURE( pViewData, "ViewData not found! :-/" );
534 
535  if ( pViewData && pDoc )
536  {
537  ScDBCollection* pDBColl = pDoc->GetDBCollection();
538  const SCTAB nCurTab = pViewData->GetTabNo();
540 
541  m_xLbOutPos->clear();
542  m_xLbOutPos->append_text(aStrUndefined);
543  m_xLbOutPos->set_sensitive(false);
544 
545  ScAreaNameIterator aIter( *pDoc );
546  OUString aName;
547  ScRange aRange;
548  while ( aIter.Next( aName, aRange ) )
549  {
550  OUString aRefStr(aRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDoc, eConv));
551  m_xLbOutPos->append(aRefStr, aName);
552  }
553 
554  m_xLbOutPos->set_active(0);
555  m_xEdOutPos->set_text(EMPTY_OUSTRING);
556 
557  // Check whether the field that is passed on is a database field:
558 
559  if ( pDBColl )
560  {
561  ScDBData* pDBData
562  = pDBColl->GetDBAtArea( nCurTab,
565  if ( pDBData )
566  {
567  m_xBtnHeader->set_active(pDBData->HasHeader());
568  }
569  }
570 
571  m_xBtnHeader->set_label(aStrColLabel);
572  }
573 
575 
576  // get available languages
577 
578  m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
579  m_xLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
580 }
581 
582 std::unique_ptr<SfxTabPage> ScTabPageSortOptions::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rArgSet)
583 {
584  return std::make_unique<ScTabPageSortOptions>(pPage, pController, *rArgSet);
585 }
586 
587 void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
588 {
589  if ( aSortData.bUserDef )
590  {
591  m_xBtnSortUser->set_active(true);
592  m_xLbSortUser->set_sensitive(true);
593  m_xLbSortUser->set_active(aSortData.nUserIndex);
594  }
595  else
596  {
597  m_xBtnSortUser->set_active(false);
598  m_xLbSortUser->set_sensitive(false);
599  m_xLbSortUser->set_active(0);
600  }
601 
602  m_xBtnCase->set_active( aSortData.bCaseSens );
604  m_xBtnHeader->set_active( aSortData.bHasHeader );
608 
609  if ( aSortData.bByRow )
610  {
611  m_xBtnTopDown->set_active(true);
612  m_xBtnHeader->set_label( aStrColLabel );
613  }
614  else
615  {
616  m_xBtnLeftRight->set_active(true);
617  m_xBtnHeader->set_label( aStrRowLabel );
618  }
619 
621  if ( eLang == LANGUAGE_DONTKNOW )
622  eLang = LANGUAGE_SYSTEM;
623  m_xLbLanguage->set_active_id(eLang);
624  FillAlgor(); // get algorithms, select default
625  if ( !aSortData.aCollatorAlgorithm.isEmpty() )
626  m_xLbAlgorithm->set_active_text(m_xColRes->GetTranslation(aSortData.aCollatorAlgorithm));
627 
628  if ( pDoc && !aSortData.bInplace )
629  {
633 
637 
638  OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
639  m_xBtnCopyResult->set_active(true);
640  m_xLbOutPos->set_sensitive(true);
641  m_xEdOutPos->set_sensitive(true);
642  m_xEdOutPos->set_text( aStr );
643  EdOutPosModHdl();
644  m_xEdOutPos->grab_focus();
645  m_xEdOutPos->select_region(0, -1);
646  }
647  else
648  {
649  m_xBtnCopyResult->set_active( false );
650  m_xLbOutPos->set_sensitive(false);
651  m_xEdOutPos->set_sensitive(false);
652  m_xEdOutPos->set_text( EMPTY_OUSTRING );
653  }
654 }
655 
657 {
658  // Create local copy of ScParam
659  ScSortParam aNewSortData = aSortData;
660 
661  const SfxItemSet* pExample = GetDialogExampleSet();
662  if (pExample)
663  {
664  const SfxPoolItem* pItem;
665  if (pExample->GetItemState(nWhichSort, true, &pItem) == SfxItemState::SET)
666  aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
667  }
668  aNewSortData.bByRow = m_xBtnTopDown->get_active();
669  aNewSortData.bHasHeader = m_xBtnHeader->get_active();
670  aNewSortData.bCaseSens = m_xBtnCase->get_active();
671  aNewSortData.bNaturalSort = m_xBtnNaturalSort->get_active();
672  aNewSortData.aDataAreaExtras.mbCellNotes = m_xBtnIncComments->get_active();
673  aNewSortData.aDataAreaExtras.mbCellDrawObjects = m_xBtnIncImages->get_active();
674  aNewSortData.aDataAreaExtras.mbCellFormats = m_xBtnFormats->get_active();
675  aNewSortData.bInplace = !m_xBtnCopyResult->get_active();
676  aNewSortData.nDestCol = theOutPos.Col();
677  aNewSortData.nDestRow = theOutPos.Row();
678  aNewSortData.nDestTab = theOutPos.Tab();
679  aNewSortData.bUserDef = m_xBtnSortUser->get_active();
680  aNewSortData.nUserIndex = (m_xBtnSortUser->get_active())
681  ? m_xLbSortUser->get_active()
682  : 0;
683 
684  // get locale
685  LanguageType eLang = m_xLbLanguage->get_active_id();
686  aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);
687 
688  // get algorithm
689  OUString sAlg;
690  if ( eLang != LANGUAGE_SYSTEM )
691  {
692  uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms(
693  aNewSortData.aCollatorLocale );
694  const int nSel = m_xLbAlgorithm->get_active();
695  if ( nSel < aAlgos.getLength() )
696  sAlg = aAlgos[nSel];
697  }
698  aNewSortData.aCollatorAlgorithm = sAlg;
699 
700  rArgSet->Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
701 
702  return true;
703 }
704 
705 // for data exchange without dialogue detour:
707 {
708  // Refresh local copy with shared data
709  aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
710  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
711  if (!pDlg)
712  return;
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 
731 {
732  bool bPosInputOk = true;
733 
734  if ( m_xBtnCopyResult->get_active() )
735  {
736  OUString thePosStr = m_xEdOutPos->get_text();
737  ScAddress thePos;
738  sal_Int32 nColonPos = thePosStr.indexOf( ':' );
739 
740  if ( -1 != nColonPos )
741  thePosStr = thePosStr.copy( 0, nColonPos );
742 
743  if ( pViewData )
744  {
745  // visible table is default for input without table
746  // must be changed to GetRefTabNo when sorting has RefInput!
747  thePos.SetTab( pViewData->GetTabNo() );
748  }
749 
750  ScRefFlags nResult = thePos.Parse( thePosStr, *pDoc, pDoc->GetAddressConvention() );
751 
752  bPosInputOk = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID;
753 
754  if ( !bPosInputOk )
755  {
756  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
757  VclMessageType::Warning, VclButtonsType::Ok,
758  ScResId(STR_INVALID_TABREF)));
759  xBox->run();
760  m_xEdOutPos->grab_focus();
761  m_xEdOutPos->select_region(0, -1);
762  theOutPos.Set(0,0,0);
763  }
764  else
765  {
766  m_xEdOutPos->set_text(thePosStr);
767  theOutPos = thePos;
768  }
769  }
770 
771  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
772  if (pDlg && bPosInputOk)
773  {
774  pDlg->SetHeaders( m_xBtnHeader->get_active() );
775  pDlg->SetByRows ( m_xBtnTopDown->get_active() );
776  }
777 
778  if ( pSetP && bPosInputOk )
779  FillItemSet( pSetP );
780 
781  return bPosInputOk ? DeactivateRC::LeavePage : DeactivateRC::KeepPage;
782 }
783 
785 {
786  ScUserList* pUserLists = ScGlobal::GetUserList();
787 
788  m_xLbSortUser->clear();
789  if ( pUserLists )
790  {
791  size_t nCount = pUserLists->size();
792  for (size_t i=0; i<nCount; ++i)
793  m_xLbSortUser->append_text((*pUserLists)[i].GetString());
794  }
795 }
796 
797 // Handler:
798 
799 IMPL_LINK( ScTabPageSortOptions, EnableHdl, weld::Toggleable&, rButton, void )
800 {
801  if (&rButton == m_xBtnCopyResult.get())
802  {
803  if (rButton.get_active())
804  {
805  m_xLbOutPos->set_sensitive(true);
806  m_xEdOutPos->set_sensitive(true);
807  m_xEdOutPos->grab_focus();
808  }
809  else
810  {
811  m_xLbOutPos->set_sensitive(false);
812  m_xEdOutPos->set_sensitive(false);
813  }
814  }
815  else if (&rButton == m_xBtnSortUser.get())
816  {
817  if (rButton.get_active())
818  {
819  m_xLbSortUser->set_sensitive(true);
820  m_xLbSortUser->grab_focus();
821  }
822  else
823  m_xLbSortUser->set_sensitive(false);
824  }
825 }
826 
827 IMPL_LINK(ScTabPageSortOptions, SelOutPosHdl, weld::ComboBox&, rLb, void)
828 {
829  if (&rLb == m_xLbOutPos.get())
830  {
831  OUString aString;
832  const int nSelPos = m_xLbOutPos->get_active();
833 
834  if (nSelPos > 0)
835  aString = m_xLbOutPos->get_id(nSelPos);
836 
837  m_xEdOutPos->set_text(aString);
838  }
839 }
840 
842 {
843  if (m_xBtnTopDown->get_active())
844  m_xBtnHeader->set_label(aStrColLabel);
845  else
846  m_xBtnHeader->set_label(aStrRowLabel);
847 }
848 
850 {
851  OUString theCurPosStr = m_xEdOutPos->get_text();
852  ScRefFlags nResult = ScAddress().Parse( theCurPosStr, *pDoc, pDoc->GetAddressConvention() );
853 
854  if ( (nResult & ScRefFlags::VALID) != ScRefFlags::VALID )
855  return;
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 
874 {
875  m_xLbAlgorithm->freeze();
876  m_xLbAlgorithm->clear();
877 
878  LanguageType eLang = m_xLbLanguage->get_active_id();
879  if ( eLang == LANGUAGE_SYSTEM )
880  {
881  // for LANGUAGE_SYSTEM no algorithm can be selected because
882  // it wouldn't necessarily exist for other languages
883  // -> leave list box empty if LANGUAGE_SYSTEM is selected
884  m_xFtAlgorithm->set_sensitive( false ); // nothing to select
885  m_xLbAlgorithm->set_sensitive( false ); // nothing to select
886  }
887  else
888  {
889  lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
890  const uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms( aLocale );
891 
892  tools::Long nCount = aAlgos.getLength();
893  for (const OUString& sAlg : aAlgos)
894  {
895  OUString sUser = m_xColRes->GetTranslation( sAlg );
896  m_xLbAlgorithm->append_text(sUser);
897  }
898  m_xLbAlgorithm->set_active(0); // first entry is default
899  m_xFtAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
900  m_xLbAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
901  }
902 
903  m_xLbAlgorithm->thaw();
904 }
905 
907 {
908  FillAlgor();
909 }
910 
911 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool Next(OUString &rName, ScRange &rRange)
Definition: rangeutl.cxx:999
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
::std::vector< ScSortKeyState > maKeyState
Definition: sortparam.hxx:121
sal_uInt16 nUserIndex
Definition: sortparam.hxx:110
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2116
Collection of user-defined sort lists.
Definition: userlist.hxx:66
static SC_DLLPUBLIC OUString ReplaceOrAppend(const OUString &rString, std::u16string_view rPlaceholder, const OUString &rReplacement)
Replaces the first occurrence of rPlaceholder in rString with rReplacement, or if rPlaceholder is not...
Definition: global.cxx:1093
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:814
std::unique_ptr< weld::ComboBox > m_xLbAlgorithm
Definition: tpsort.hxx:133
ScAddress aStart
Definition: address.hxx:499
ScViewData * GetViewData() const
Definition: uiitems.hxx:140
IMPL_LINK(ScTabPageSortFields, SelectHdl, weld::ComboBox &, rLb, void)
Definition: tpsort.cxx:426
std::unique_ptr< weld::CheckButton > m_xBtnSortUser
Definition: tpsort.hxx:129
#define EMPTY_OUSTRING
Definition: global.hxx:214
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:89
SCROW Row() const
Definition: address.hxx:261
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:656
OUString aStrUndefined
Definition: tpsort.hxx:60
css::lang::Locale aCollatorLocale
Definition: sortparam.hxx:122
SCCOL nDestCol
Definition: sortparam.hxx:118
bool HasHeader() const
Definition: dbdata.hxx:130
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:481
static LanguageType convertToLanguageType(const css::lang::Locale &rLocale, bool bResolveSystem=true)
ScSortParam aSortData
Definition: tpsort.hxx:114
long Long
sal_Int64 n
void ScColToAlpha(OUStringBuffer &rBuf, SCCOL nCol)
append alpha representation of column to buffer
Definition: address.cxx:1926
sal_uInt16 GetFieldSelPos(SCCOLROW nField)
Definition: tpsort.cxx:388
#define max(a, b)
virtual void ActivatePage(const SfxItemSet &rSet) override
Definition: tpsort.cxx:276
SCTAB GetTabNo() const
Definition: viewdata.hxx:394
size_t size() const
Definition: userlist.cxx:345
ScDocument & GetDocument() const
Definition: viewdata.hxx:379
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:730
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:494
std::unique_ptr< weld::CheckButton > m_xBtnHeader
Definition: tpsort.hxx:123
ScAddress theOutPos
Definition: tpsort.hxx:117
ScSortParam aSortData
Definition: tpsort.hxx:66
bool mbCellDrawObjects
If TRUE, consider the presence of draw objects anchored to the cell.
Definition: sortparam.hxx:48
std::unique_ptr< weld::CheckButton > m_xBtnNaturalSort
Definition: tpsort.hxx:125
void SetLastSortKey(sal_uInt16 nItem)
Definition: tpsort.cxx:405
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
bool bNaturalSort
Definition: sortparam.hxx:114
void SetExchangeSupport()
int nCount
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3517
SCTAB Tab() const
Definition: address.hxx:270
std::unique_ptr< weld::CheckButton > m_xBtnCopyResult
Definition: tpsort.hxx:126
ScViewData * pViewData
Definition: tpsort.hxx:65
std::unique_ptr< weld::CheckButton > m_xBtnIncComments
Definition: tpsort.hxx:136
bool mbCellNotes
If TRUE, consider the presence of cell notes besides data.
Definition: sortparam.hxx:46
const ScDBData * GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
Definition: dbdata.cxx:1345
const SfxItemSet & GetItemSet() const
void SetDebugName(const char *pDebugName)
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: tpsort.cxx:299
void SetTab(SCTAB nTabP)
Definition: address.hxx:282
virtual ~ScTabPageSortFields() override
Definition: tpsort.cxx:102
#define SCITEM_SORTDATA
Definition: scitems.hxx:89
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
bool GetHeaders() const
Definition: sortdlg.hxx:32
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:405
#define LANGUAGE_SYSTEM
sal_Int16 SCCOL
Definition: types.hxx:21
std::unique_ptr< weld::Container > m_xBox
Definition: tpsort.hxx:75
ScSortKeyWindow m_aSortWin
Definition: tpsort.hxx:76
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:873
void FillUserSortListBox()
Definition: tpsort.cxx:784
SC_DLLPUBLIC SCCOL ClampToAllocatedColumns(SCTAB nTab, SCCOL nCol) const
Definition: documen3.cxx:2148
float u
static SC_DLLPUBLIC ScUserList * GetUserList()
Definition: global.cxx:276
#define LANGUAGE_DONTKNOW
virtual bool FillItemSet(SfxItemSet *rArgSet) override
Definition: tpsort.cxx:213
void FillFieldLists(sal_uInt16 nStartField)
Definition: tpsort.cxx:316
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:127
bool bCaseSens
Definition: sortparam.hxx:113
OUString aStrColumn
Definition: tpsort.hxx:61
void AddSortKey(sal_uInt16 nItem)
Definition: sortkeydlg.cxx:51
ScSortKeyItems m_aSortKeyItems
Definition: sortkeydlg.hxx:39
std::unique_ptr< weld::RadioButton > m_xBtnTopDown
Definition: tpsort.hxx:134
const SfxItemSet * GetDialogExampleSet() const
ScDataAreaExtras aDataAreaExtras
Definition: sortparam.hxx:109
SCCOL Col() const
Definition: address.hxx:266
std::unique_ptr< CollatorWrapper > m_xColWrap
Definition: tpsort.hxx:120
virtual void ActivatePage(const SfxItemSet &rSet) override
Definition: tpsort.cxx:706
sal_uInt16 nFieldCount
Definition: tpsort.hxx:68
void AddSortKey(sal_uInt16 nItem)
Definition: tpsort.cxx:473
std::unique_ptr< weld::CheckButton > m_xBtnIncImages
Definition: tpsort.hxx:137
std::unique_ptr< weld::CheckButton > m_xBtnFormats
Definition: tpsort.hxx:124
bool mbCellFormats
If TRUE, consider the presence of cell formats.
Definition: sortparam.hxx:50
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:17
std::unique_ptr< CollatorResource > m_xColRes
Definition: tpsort.hxx:119
weld::Window * GetFrameWeld() const
bool bHasHeader
Definition: sortparam.hxx:111
virtual void Reset(const SfxItemSet *rArgSet) override
Definition: tpsort.cxx:587
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:468
virtual void Reset(const SfxItemSet *rArgSet) override
Definition: tpsort.cxx:132
sal_uInt16 GetSortKeyCount() const
Definition: sortparam.hxx:139
OUString aName
void SetByRows(bool bByRows)
Definition: sortdlg.hxx:31
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:123
OUString aStrColLabel
Definition: tpsort.hxx:110
std::vector< SCCOLROW > nFieldArr
Definition: tpsort.hxx:67
SCCOL SC_MAXFIELDS(const ScSheetLimits &rLimits)
Definition: tpsort.hxx:37
ScTabPageSortFields(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rArgSet)
Definition: tpsort.cxx:71
DeactivateRC
virtual void Start(bool bStartTimer=true) override
void SetHeaders(bool bHeaders)
Definition: sortdlg.hxx:30
SCROW nDestRow
Definition: sortparam.hxx:119
SVXCORE_DLLPUBLIC MSO_SPT Get(const OUString &)
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, 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:1548
std::unique_ptr< weld::CheckButton > m_xBtnCase
Definition: tpsort.hxx:122
ScRefFlags
Definition: address.hxx:144
bool GetByRows() const
Definition: sortdlg.hxx:33
#define DEFSORT
Definition: sortparam.hxx:22
OUString aStrRowLabel
Definition: tpsort.hxx:109
ScDocument * pDoc
Definition: tpsort.hxx:116
aStr
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
sal_Int16 SCTAB
Definition: types.hxx:22
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *pArgSet)
Definition: tpsort.cxx:582
SCCOL GetCurX() const
Definition: viewdata.hxx:400
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
SCTAB nDestTab
Definition: sortparam.hxx:117