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  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
280  if (!pDlg)
281  return;
282 
283  if ( bHasHeader == pDlg->GetHeaders() && bSortByRows == pDlg->GetByRows() )
284  return;
285 
286  std::vector<sal_uInt16> nCurSel;
287  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
288  nCurSel.push_back( m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active() );
289 
290  bHasHeader = pDlg->GetHeaders();
291  bSortByRows = pDlg->GetByRows();
292  FillFieldLists(0);
293 
294  for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
295  m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(nCurSel[i]);
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  return;
319 
320  ScDocument& rDoc = pViewData->GetDocument();
321 
322  for (sal_uInt16 j = nStartField; j < nSortKeyCount; ++j)
323  {
324  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->clear();
325  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->freeze();
326  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->append_text(aStrUndefined);
327  }
328 
329  SCCOL nFirstSortCol = aSortData.nCol1;
330  SCROW nFirstSortRow = aSortData.nRow1;
331  SCTAB nTab = pViewData->GetTabNo();
332  sal_uInt16 i = 1;
333  nFieldArr.clear();
334  nFieldArr.push_back(0);
335 
336  if ( bSortByRows )
337  {
338  OUString aFieldName;
339  SCCOL nMaxCol = rDoc.ClampToAllocatedColumns(nTab, aSortData.nCol2);
340  SCCOL col;
341 
342  for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
343  {
344  aFieldName = rDoc.GetString(col, nFirstSortRow, nTab);
345  if ( !bHasHeader || aFieldName.isEmpty() )
346  {
347  aFieldName = ScGlobal::ReplaceOrAppend( aStrColumn, "%1", ScColToAlpha( col ));
348  }
349  nFieldArr.push_back( col );
350 
351  for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
352  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
353 
354  i++;
355  }
356  }
357  else
358  {
359  OUString aFieldName;
360  SCROW nMaxRow = aSortData.nRow2;
361  SCROW row;
362 
363  for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS; row++ )
364  {
365  aFieldName = rDoc.GetString(nFirstSortCol, row, nTab);
366  if ( !bHasHeader || aFieldName.isEmpty() )
367  {
368  aFieldName = ScGlobal::ReplaceOrAppend( aStrRow, "%1", OUString::number( row+1));
369  }
370  nFieldArr.push_back( row );
371 
372  for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
373  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
374 
375  i++;
376  }
377  }
378 
379  for (sal_uInt16 j=nStartField; j < nSortKeyCount; ++j)
380  {
381  m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->thaw();
382  }
383 
384  nFieldCount = i;
385 }
386 
388 {
389  sal_uInt16 nFieldPos = 0;
390  bool bFound = false;
391 
392  for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
393  {
394  if ( nFieldArr[n] == nField )
395  {
396  nFieldPos = n;
397  bFound = true;
398  }
399  }
400 
401  return nFieldPos;
402 }
403 
404 void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )
405 {
406  // Extend local SortParam copy
407  const ScSortKeyState atempKeyState = { 0, false, true };
408  aSortData.maKeyState.push_back( atempKeyState );
409 
410  // Add Sort Key Item
411  ++nSortKeyCount;
413  m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->connect_changed(
414  LINK( this, ScTabPageSortFields, SelectHdl ) );
415 
416  FillFieldLists( nItem );
417 
418  // Set Status
419  m_aSortWin.m_aSortKeyItems[nItem]->m_xBtnUp->set_active(true);
420  m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->set_active(0);
421 }
422 
423 // Handler:
424 
425 IMPL_LINK( ScTabPageSortFields, SelectHdl, weld::ComboBox&, rLb, void )
426 {
427  OUString aSelEntry = rLb.get_active_text();
428  ScSortKeyItems::iterator pIter;
429 
430  // If last listbox is enabled add one item
431  if (m_aSortWin.m_aSortKeyItems.back()->m_xLbSort.get() == &rLb)
432  {
433  if ( aSelEntry != aStrUndefined )
434  {
435  SetLastSortKey( nSortKeyCount );
436  return;
437  }
438  }
439 
440  // Find selected listbox
441  pIter = std::find_if(m_aSortWin.m_aSortKeyItems.begin(), m_aSortWin.m_aSortKeyItems.end(),
442  [&rLb](const ScSortKeyItems::value_type& rItem) { return rItem->m_xLbSort.get() == &rLb; });
443 
444  if (pIter == m_aSortWin.m_aSortKeyItems.end())
445  return;
446 
447  // If not selecting the last Listbox, modify the succeeding ones
448  ++pIter;
449  if ( std::distance(m_aSortWin.m_aSortKeyItems.begin(), pIter) >= nSortKeyCount )
450  return;
451 
452  if ( aSelEntry == aStrUndefined )
453  {
454  for ( ; pIter != m_aSortWin.m_aSortKeyItems.end(); ++pIter )
455  {
456  (*pIter)->m_xLbSort->set_active(0);
457 
458  (*pIter)->DisableField();
459  }
460  }
461  else
462  {
463  (*pIter)->EnableField();
464  }
465 }
466 
467 IMPL_LINK_NOARG(ScTabPageSortFields, ScrollToEndHdl, Timer*, void)
468 {
469  m_xScrolledWindow->vadjustment_set_value(m_xScrolledWindow->vadjustment_get_upper());
470 }
471 
472 void ScTabPageSortFields::AddSortKey( sal_uInt16 nItem )
473 {
474  m_aSortWin.AddSortKey(nItem);
475  m_aIdle.Start();
476 }
477 
478 // Sort option Tab Page:
479 
481  : SfxTabPage(pPage, pController, "modules/scalc/ui/sortoptionspage.ui", "SortOptionsPage", &rArgSet)
482  , aStrRowLabel(ScResId(SCSTR_ROW_LABEL))
483  , aStrColLabel(ScResId(SCSTR_COL_LABEL))
484  , aStrUndefined(ScResId(SCSTR_UNDEFINED))
485  , nWhichSort(rArgSet.GetPool()->GetWhich(SID_SORT))
486  , aSortData(static_cast<const ScSortItem&>(rArgSet.Get(nWhichSort)).GetSortData())
487  , pViewData(nullptr)
488  , pDoc(nullptr)
489  , m_xBtnCase(m_xBuilder->weld_check_button("case"))
490  , m_xBtnHeader(m_xBuilder->weld_check_button("header"))
491  , m_xBtnFormats(m_xBuilder->weld_check_button("formats"))
492  , m_xBtnNaturalSort(m_xBuilder->weld_check_button("naturalsort"))
493  , m_xBtnCopyResult(m_xBuilder->weld_check_button("copyresult"))
494  , m_xLbOutPos(m_xBuilder->weld_combo_box("outarealb"))
495  , m_xEdOutPos(m_xBuilder->weld_entry("outareaed"))
496  , m_xBtnSortUser(m_xBuilder->weld_check_button("sortuser"))
497  , m_xLbSortUser(m_xBuilder->weld_combo_box("sortuserlb"))
498  , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
499  , m_xFtAlgorithm(m_xBuilder->weld_label("algorithmft"))
500  , m_xLbAlgorithm(m_xBuilder->weld_combo_box("algorithmlb"))
501  , m_xBtnTopDown(m_xBuilder->weld_radio_button("topdown"))
502  , m_xBtnLeftRight(m_xBuilder->weld_radio_button("leftright"))
503  , m_xBtnIncComments(m_xBuilder->weld_check_button("includenotes"))
504  , m_xBtnIncImages(m_xBuilder->weld_check_button("includeimages"))
505 {
506  m_xLbSortUser->set_size_request(m_xLbSortUser->get_approximate_digit_width() * 50, -1);
507  Init();
509 }
510 
512 {
513  // CollatorResource has user-visible names for sort algorithms
514  m_xColRes.reset(new CollatorResource);
515 
518 
519  const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
520  GetItemSet().Get( nWhichSort ));
521 
522  m_xLbOutPos->connect_changed( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
523  m_xBtnCopyResult->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
524  m_xBtnSortUser->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
525  m_xBtnTopDown->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
526  m_xBtnLeftRight->connect_toggled( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
527  m_xLbLanguage->connect_changed( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
528 
529  pViewData = rSortItem.GetViewData();
530  pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
531 
532  OSL_ENSURE( pViewData, "ViewData not found! :-/" );
533 
534  if ( pViewData && pDoc )
535  {
536  ScDBCollection* pDBColl = pDoc->GetDBCollection();
537  const SCTAB nCurTab = pViewData->GetTabNo();
539 
540  m_xLbOutPos->clear();
541  m_xLbOutPos->append_text(aStrUndefined);
542  m_xLbOutPos->set_sensitive(false);
543 
544  ScAreaNameIterator aIter( *pDoc );
545  OUString aName;
546  ScRange aRange;
547  while ( aIter.Next( aName, aRange ) )
548  {
549  OUString aRefStr(aRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDoc, eConv));
550  m_xLbOutPos->append(aRefStr, aName);
551  }
552 
553  m_xLbOutPos->set_active(0);
554  m_xEdOutPos->set_text(EMPTY_OUSTRING);
555 
556  // Check whether the field that is passed on is a database field:
557 
558  if ( pDBColl )
559  {
560  ScDBData* pDBData
561  = pDBColl->GetDBAtArea( nCurTab,
564  if ( pDBData )
565  {
566  m_xBtnHeader->set_active(pDBData->HasHeader());
567  }
568  }
569 
570  m_xBtnHeader->set_label(aStrColLabel);
571  }
572 
574 
575  // get available languages
576 
577  m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
578  m_xLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
579 }
580 
581 std::unique_ptr<SfxTabPage> ScTabPageSortOptions::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rArgSet)
582 {
583  return std::make_unique<ScTabPageSortOptions>(pPage, pController, *rArgSet);
584 }
585 
586 void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
587 {
588  if ( aSortData.bUserDef )
589  {
590  m_xBtnSortUser->set_active(true);
591  m_xLbSortUser->set_sensitive(true);
592  m_xLbSortUser->set_active(aSortData.nUserIndex);
593  }
594  else
595  {
596  m_xBtnSortUser->set_active(false);
597  m_xLbSortUser->set_sensitive(false);
598  m_xLbSortUser->set_active(0);
599  }
600 
601  m_xBtnCase->set_active( aSortData.bCaseSens );
602  m_xBtnFormats->set_active( aSortData.bIncludePattern );
603  m_xBtnHeader->set_active( aSortData.bHasHeader );
607 
608  if ( aSortData.bByRow )
609  {
610  m_xBtnTopDown->set_active(true);
611  m_xBtnHeader->set_label( aStrColLabel );
612  }
613  else
614  {
615  m_xBtnLeftRight->set_active(true);
616  m_xBtnHeader->set_label( aStrRowLabel );
617  }
618 
620  if ( eLang == LANGUAGE_DONTKNOW )
621  eLang = LANGUAGE_SYSTEM;
622  m_xLbLanguage->set_active_id(eLang);
623  FillAlgor(); // get algorithms, select default
624  if ( !aSortData.aCollatorAlgorithm.isEmpty() )
625  m_xLbAlgorithm->set_active_text(m_xColRes->GetTranslation(aSortData.aCollatorAlgorithm));
626 
627  if ( pDoc && !aSortData.bInplace )
628  {
632 
636 
637  OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
638  m_xBtnCopyResult->set_active(true);
639  m_xLbOutPos->set_sensitive(true);
640  m_xEdOutPos->set_sensitive(true);
641  m_xEdOutPos->set_text( aStr );
642  EdOutPosModHdl();
643  m_xEdOutPos->grab_focus();
644  m_xEdOutPos->select_region(0, -1);
645  }
646  else
647  {
648  m_xBtnCopyResult->set_active( false );
649  m_xLbOutPos->set_sensitive(false);
650  m_xEdOutPos->set_sensitive(false);
651  m_xEdOutPos->set_text( EMPTY_OUSTRING );
652  }
653 }
654 
656 {
657  // Create local copy of ScParam
658  ScSortParam aNewSortData = aSortData;
659 
660  const SfxItemSet* pExample = GetDialogExampleSet();
661  if (pExample)
662  {
663  const SfxPoolItem* pItem;
664  if (pExample->GetItemState(nWhichSort, true, &pItem) == SfxItemState::SET)
665  aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
666  }
667  aNewSortData.bByRow = m_xBtnTopDown->get_active();
668  aNewSortData.bHasHeader = m_xBtnHeader->get_active();
669  aNewSortData.bCaseSens = m_xBtnCase->get_active();
670  aNewSortData.bNaturalSort = m_xBtnNaturalSort->get_active();
671  aNewSortData.bIncludeComments= m_xBtnIncComments->get_active();
672  aNewSortData.bIncludeGraphicObjects = m_xBtnIncImages->get_active();
673  aNewSortData.bIncludePattern = m_xBtnFormats->get_active();
674  aNewSortData.bInplace = !m_xBtnCopyResult->get_active();
675  aNewSortData.nDestCol = theOutPos.Col();
676  aNewSortData.nDestRow = theOutPos.Row();
677  aNewSortData.nDestTab = theOutPos.Tab();
678  aNewSortData.bUserDef = m_xBtnSortUser->get_active();
679  aNewSortData.nUserIndex = (m_xBtnSortUser->get_active())
680  ? m_xLbSortUser->get_active()
681  : 0;
682 
683  // get locale
684  LanguageType eLang = m_xLbLanguage->get_active_id();
685  aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);
686 
687  // get algorithm
688  OUString sAlg;
689  if ( eLang != LANGUAGE_SYSTEM )
690  {
691  uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms(
692  aNewSortData.aCollatorLocale );
693  const int nSel = m_xLbAlgorithm->get_active();
694  if ( nSel < aAlgos.getLength() )
695  sAlg = aAlgos[nSel];
696  }
697  aNewSortData.aCollatorAlgorithm = sAlg;
698 
699  rArgSet->Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
700 
701  return true;
702 }
703 
704 // for data exchange without dialogue detour:
706 {
707  // Refresh local copy with shared data
708  aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
709  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
710  if (!pDlg)
711  return;
712 
713  if ( m_xBtnHeader->get_active() != pDlg->GetHeaders() )
714  {
715  m_xBtnHeader->set_active( pDlg->GetHeaders() );
716  }
717 
718  if ( m_xBtnTopDown->get_active() != pDlg->GetByRows() )
719  {
720  m_xBtnTopDown->set_active( pDlg->GetByRows() );
721  m_xBtnLeftRight->set_active( !pDlg->GetByRows() );
722  }
723 
724  m_xBtnHeader->set_label( (pDlg->GetByRows())
725  ? aStrColLabel
726  : aStrRowLabel );
727 }
728 
730 {
731  bool bPosInputOk = true;
732 
733  if ( m_xBtnCopyResult->get_active() )
734  {
735  OUString thePosStr = m_xEdOutPos->get_text();
736  ScAddress thePos;
737  sal_Int32 nColonPos = thePosStr.indexOf( ':' );
738 
739  if ( -1 != nColonPos )
740  thePosStr = thePosStr.copy( 0, nColonPos );
741 
742  if ( pViewData )
743  {
744  // visible table is default for input without table
745  // must be changed to GetRefTabNo when sorting has RefInput!
746  thePos.SetTab( pViewData->GetTabNo() );
747  }
748 
749  ScRefFlags nResult = thePos.Parse( thePosStr, *pDoc, pDoc->GetAddressConvention() );
750 
751  bPosInputOk = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID;
752 
753  if ( !bPosInputOk )
754  {
755  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
756  VclMessageType::Warning, VclButtonsType::Ok,
757  ScResId(STR_INVALID_TABREF)));
758  xBox->run();
759  m_xEdOutPos->grab_focus();
760  m_xEdOutPos->select_region(0, -1);
761  theOutPos.Set(0,0,0);
762  }
763  else
764  {
765  m_xEdOutPos->set_text(thePosStr);
766  theOutPos = thePos;
767  }
768  }
769 
770  ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
771  if (pDlg && bPosInputOk)
772  {
773  pDlg->SetHeaders( m_xBtnHeader->get_active() );
774  pDlg->SetByRows ( m_xBtnTopDown->get_active() );
775  }
776 
777  if ( pSetP && bPosInputOk )
778  FillItemSet( pSetP );
779 
780  return bPosInputOk ? DeactivateRC::LeavePage : DeactivateRC::KeepPage;
781 }
782 
784 {
785  ScUserList* pUserLists = ScGlobal::GetUserList();
786 
787  m_xLbSortUser->clear();
788  if ( pUserLists )
789  {
790  size_t nCount = pUserLists->size();
791  for (size_t i=0; i<nCount; ++i)
792  m_xLbSortUser->append_text((*pUserLists)[i].GetString());
793  }
794 }
795 
796 // Handler:
797 
798 IMPL_LINK( ScTabPageSortOptions, EnableHdl, weld::ToggleButton&, rButton, void )
799 {
800  if (&rButton == m_xBtnCopyResult.get())
801  {
802  if (rButton.get_active())
803  {
804  m_xLbOutPos->set_sensitive(true);
805  m_xEdOutPos->set_sensitive(true);
806  m_xEdOutPos->grab_focus();
807  }
808  else
809  {
810  m_xLbOutPos->set_sensitive(false);
811  m_xEdOutPos->set_sensitive(false);
812  }
813  }
814  else if (&rButton == m_xBtnSortUser.get())
815  {
816  if (rButton.get_active())
817  {
818  m_xLbSortUser->set_sensitive(true);
819  m_xLbSortUser->grab_focus();
820  }
821  else
822  m_xLbSortUser->set_sensitive(false);
823  }
824 }
825 
826 IMPL_LINK(ScTabPageSortOptions, SelOutPosHdl, weld::ComboBox&, rLb, void)
827 {
828  if (&rLb == m_xLbOutPos.get())
829  {
830  OUString aString;
831  const int nSelPos = m_xLbOutPos->get_active();
832 
833  if (nSelPos > 0)
834  aString = m_xLbOutPos->get_id(nSelPos);
835 
836  m_xEdOutPos->set_text(aString);
837  }
838 }
839 
841 {
842  if (m_xBtnTopDown->get_active())
843  m_xBtnHeader->set_label(aStrColLabel);
844  else
845  m_xBtnHeader->set_label(aStrRowLabel);
846 }
847 
849 {
850  OUString theCurPosStr = m_xEdOutPos->get_text();
851  ScRefFlags nResult = ScAddress().Parse( theCurPosStr, *pDoc, pDoc->GetAddressConvention() );
852 
853  if ( (nResult & ScRefFlags::VALID) != ScRefFlags::VALID )
854  return;
855 
856  bool bFound = false;
857  sal_Int32 i = 0;
858  const int nCount = m_xLbOutPos->get_count();
859 
860  for ( i=2; i<nCount && !bFound; i++ )
861  {
862  OUString aStr = m_xLbOutPos->get_id(i);
863  bFound = (theCurPosStr == aStr);
864  }
865 
866  if ( bFound )
867  m_xLbOutPos->set_active(--i);
868  else
869  m_xLbOutPos->set_active(0);
870 }
871 
873 {
874  m_xLbAlgorithm->freeze();
875  m_xLbAlgorithm->clear();
876 
877  LanguageType eLang = m_xLbLanguage->get_active_id();
878  if ( eLang == LANGUAGE_SYSTEM )
879  {
880  // for LANGUAGE_SYSTEM no algorithm can be selected because
881  // it wouldn't necessarily exist for other languages
882  // -> leave list box empty if LANGUAGE_SYSTEM is selected
883  m_xFtAlgorithm->set_sensitive( false ); // nothing to select
884  m_xLbAlgorithm->set_sensitive( false ); // nothing to select
885  }
886  else
887  {
888  lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
889  const uno::Sequence<OUString> aAlgos = m_xColWrap->listCollatorAlgorithms( aLocale );
890 
891  tools::Long nCount = aAlgos.getLength();
892  for (const OUString& sAlg : aAlgos)
893  {
894  OUString sUser = m_xColRes->GetTranslation( sAlg );
895  m_xLbAlgorithm->append_text(sUser);
896  }
897  m_xLbAlgorithm->set_active(0); // first entry is default
898  m_xFtAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
899  m_xLbAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
900  }
901 
902  m_xLbAlgorithm->thaw();
903 }
904 
906 {
907  FillAlgor();
908 }
909 
910 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool Next(OUString &rName, ScRange &rRange)
Definition: rangeutl.cxx:947
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:2107
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:425
std::unique_ptr< weld::CheckButton > m_xBtnSortUser
Definition: tpsort.hxx:129
#define EMPTY_OUSTRING
Definition: global.hxx:215
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:655
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:480
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:1917
sal_uInt16 GetFieldSelPos(SCCOLROW nField)
Definition: tpsort.cxx:387
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
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
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:1069
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:729
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:489
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:404
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:3486
virtual void Start() override
SCTAB Tab() const
Definition: address.hxx:271
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
bool GetHeaders() const
Definition: sortdlg.hxx:33
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:783
SC_DLLPUBLIC SCCOL ClampToAllocatedColumns(SCTAB nTab, SCCOL nCol) const
Definition: documen3.cxx:2124
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
static SC_DLLPUBLIC ScUserList * GetUserList()
Definition: global.cxx:274
#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:48
ScSortKeyItems m_aSortKeyItems
Definition: sortkeydlg.hxx:40
#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:705
sal_uInt16 nFieldCount
Definition: tpsort.hxx:68
void AddSortKey(sal_uInt16 nItem)
Definition: tpsort.cxx:472
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:586
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:467
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 &)
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:1539
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
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:581
SCCOL GetCurX() const
Definition: viewdata.hxx:401
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
SCTAB nDestTab
Definition: sortparam.hxx:57