tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / dbgui / tpsort.cxx
blob91a7a25d3630357f1e341fe885ee486c28111a58
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #undef SC_DLLIMPLEMENTATION
22 #include <vcl/svapp.hxx>
23 #include <vcl/weld.hxx>
24 #include <i18nlangtag/languagetag.hxx>
25 #include <svtools/collatorres.hxx>
26 #include <unotools/collatorwrapper.hxx>
27 #include <comphelper/processfactory.hxx>
28 #include <osl/diagnose.h>
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>
43 #include <sortkeydlg.hxx>
45 #include <sortdlg.hxx>
47 #include <tpsort.hxx>
49 using namespace com::sun::star;
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.
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()).
60 * In the meantime the class SfxTabPage offers the following method:
62 * virtual sal_Bool HasExchangeSupport() const; -> return sal_True;
63 * virtual void ActivatePage(const SfxItemSet &);
64 * virtual int DeactivatePage(SfxItemSet * = 0);
66 * This still needs to be changed!
69 // Sort Criteria Tab page
71 ScTabPageSortFields::ScTabPageSortFields(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rArgSet)
72 : SfxTabPage(pPage, pController, u"modules/scalc/ui/sortcriteriapage.ui"_ustr, u"SortCriteriaPage"_ustr, &rArgSet)
75 m_aIdle("ScTabPageSortFields Scroll To End Idle"),
76 aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
77 aStrColumn ( ScResId( SCSTR_COLUMN ) ),
78 aStrRow ( ScResId( SCSTR_ROW ) ),
79 aStrRowLabel ( ScResId( SCSTR_ROW_LABEL ) ),
80 aStrColLabel ( ScResId( SCSTR_COL_LABEL ) ),
82 nWhichSort ( rArgSet.GetPool()->GetWhichIDFromSlotID( SID_SORT ) ),
83 pViewData ( nullptr ),
84 aSortData ( rArgSet.Get( nWhichSort ).GetSortData() ),
85 nFieldCount ( 0 ),
86 // show actual size of the sorting keys without limiting them to the default size
87 nSortKeyCount(std::max(aSortData.GetSortKeyCount(), static_cast<sal_uInt16>(DEFSORT)))
89 , m_xTop(m_xBuilder->weld_container(u"TopWindow"_ustr))
90 , m_xBtnHeader(m_xBuilder->weld_check_button(u"cbHeader"_ustr))
91 , m_xBtnTopDown(m_xBuilder->weld_radio_button(u"rbTopDown"_ustr))
92 , m_xBtnLeftRight(m_xBuilder->weld_radio_button(u"rbLeftRight"_ustr))
93 , m_xScrolledWindow(m_xBuilder->weld_scrolled_window(u"SortCriteriaPage"_ustr))
94 , m_xBox(m_xBuilder->weld_container(u"SortKeyWindow"_ustr))
95 , m_aSortWin(m_xBox.get())
97 // tdf#147722 set some nominal small default height so the height adapts
98 // to all the other contents and the natural height of this widget isn't
99 // an input into the overall size
100 m_xScrolledWindow->set_size_request(-1, 42);
102 Init();
104 m_aIdle.SetInvokeHandler(LINK(this, ScTabPageSortFields, ScrollToEndHdl));
106 SetExchangeSupport();
109 ScTabPageSortFields::~ScTabPageSortFields()
111 m_aSortWin.m_aSortKeyItems.clear();
112 m_xBox.reset();
113 m_xScrolledWindow.reset();
116 void ScTabPageSortFields::Init()
118 // Check whether the field that is passed on is a database field:
119 ScDocument* pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
120 if ( pDoc )
122 ScDBCollection* pDBColl = pDoc->GetDBCollection();
123 const SCTAB nCurTab = pViewData->GetTabNo();
124 if ( pDBColl )
126 ScDBData* pDBData
127 = pDBColl->GetDBAtArea( nCurTab,
128 aSortData.nCol1, aSortData.nRow1,
129 aSortData.nCol2, aSortData.nRow2 );
130 if ( pDBData )
132 m_xBtnHeader->set_active(pDBData->HasHeader());
136 m_xBtnHeader->set_label(aStrColLabel);
138 Link<weld::Toggleable&,void> aLink = LINK(this, ScTabPageSortFields, SortDirHdl );
139 m_xBtnTopDown->connect_toggled( aLink );
140 m_xBtnLeftRight->connect_toggled( aLink );
141 m_xBtnHeader->connect_toggled( aLink );
143 const ScSortItem& rSortItem = GetItemSet().Get( nWhichSort );
145 pViewData = rSortItem.GetViewData();
146 OSL_ENSURE( pViewData, "ViewData not found!" );
148 nFieldArr.push_back( 0 );
150 // Create three sort key dialogs by default
151 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
153 AddSortKey(i+1);
154 m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed(LINK(this, ScTabPageSortFields, SelectHdl));
158 std::unique_ptr<SfxTabPage> ScTabPageSortFields::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pArgSet)
160 return std::make_unique<ScTabPageSortFields>(pPage, pController, *pArgSet);
163 void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
165 m_xBtnHeader->set_active( aSortData.bHasHeader );
166 m_xBtnTopDown->set_active( aSortData.bByRow );
167 m_xBtnLeftRight->set_active( !aSortData.bByRow );
169 if (m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->get_count() == 0)
170 FillFieldLists(0);
172 // ListBox selection:
173 if (!aSortData.maKeyState.empty() && aSortData.maKeyState[0].bDoSort)
175 // Make sure that the all sort keys are reset
176 for ( sal_uInt16 i=nSortKeyCount; i<aSortData.GetSortKeyCount(); i++ )
178 AddSortKey(i+1);
179 m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->connect_changed( LINK( this,
180 ScTabPageSortFields, SelectHdl ) );
182 nSortKeyCount = aSortData.GetSortKeyCount();
183 FillFieldLists(0);
185 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
187 if (aSortData.maKeyState[i].bDoSort )
189 m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active( GetFieldSelPos(
190 aSortData.maKeyState[i].nField ) );
191 (aSortData.maKeyState[i].bAscending)
192 ? m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true)
193 : m_aSortWin.m_aSortKeyItems[i]->m_xBtnDown->set_active(true);
195 else
197 m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0); // Select none
198 m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
202 // Enable or disable field depending on preceding Listbox selection
203 m_aSortWin.m_aSortKeyItems[0]->EnableField();
204 for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
205 if ( m_aSortWin.m_aSortKeyItems[i - 1]->m_xLbSort->get_active() == 0 )
206 m_aSortWin.m_aSortKeyItems[i]->DisableField();
207 else
208 m_aSortWin.m_aSortKeyItems[i]->EnableField();
210 else
212 SCCOL nCol = pViewData->GetCurX();
214 if( nCol < aSortData.nCol1 )
215 nCol = aSortData.nCol1;
216 else if( nCol > aSortData.nCol2 )
217 nCol = aSortData.nCol2;
219 sal_uInt16 nSort1Pos = nCol - aSortData.nCol1+1;
221 m_aSortWin.m_aSortKeyItems[0]->m_xLbSort->set_active(nSort1Pos);
222 for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
223 m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(0);
225 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
226 m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->set_active(true);
228 m_aSortWin.m_aSortKeyItems[0]->EnableField();
229 m_aSortWin.m_aSortKeyItems[1]->EnableField();
230 for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
231 m_aSortWin.m_aSortKeyItems[i]->DisableField();
234 // Make sure that there is always a last undefined sort key
235 if (m_aSortWin.m_aSortKeyItems[nSortKeyCount - 1]->m_xLbSort->get_active() > 0)
236 SetLastSortKey( nSortKeyCount );
239 bool ScTabPageSortFields::FillItemSet( SfxItemSet* rArgSet )
241 ScSortParam aNewSortData = aSortData;
243 const SfxItemSet* pExample = GetDialogExampleSet();
244 if (pExample)
246 if (const ScSortItem* pItem = pExample->GetItemIfSet(nWhichSort))
248 ScSortParam aTempData = pItem->GetSortData();
249 aTempData.maKeyState = aNewSortData.maKeyState;
250 aNewSortData = aTempData;
253 aNewSortData.bByRow = m_xBtnTopDown->get_active();
254 aNewSortData.bHasHeader = m_xBtnHeader->get_active();
256 std::vector<sal_Int32> nSortPos;
258 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
260 nSortPos.push_back(m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active());
261 if (nSortPos[i] == -1) nSortPos[i] = 0;
264 if( nSortKeyCount >= aNewSortData.GetSortKeyCount() )
265 aNewSortData.maKeyState.resize(nSortKeyCount);
267 if ( nSortPos[0] > 0 )
269 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
271 aNewSortData.maKeyState[i].bDoSort = (nSortPos[i] > 0);
272 aNewSortData.maKeyState[i].nField = nFieldArr[nSortPos[i]];
273 aNewSortData.maKeyState[i].bAscending = m_aSortWin.m_aSortKeyItems[i]->m_xBtnUp->get_active();
276 else
278 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
279 aNewSortData.maKeyState[i].bDoSort = false;
282 rArgSet->Put( ScSortItem( SCITEM_SORTDATA, nullptr, &aNewSortData ) );
284 return true;
287 // for data exchange without dialogue detour:
288 void ScTabPageSortFields::ActivatePage( const SfxItemSet& rSet )
290 // Refresh local copy with shared data
291 aSortData = rSet.Get( SCITEM_SORTDATA ).GetSortData();
293 m_xBtnHeader->set_active( aSortData.bHasHeader );
294 m_xBtnTopDown->set_active( aSortData.bByRow );
295 m_xBtnLeftRight->set_active( !aSortData.bByRow );
298 DeactivateRC ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
300 if ( pSetP )
301 FillItemSet( pSetP );
303 return DeactivateRC::LeavePage;
306 void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
308 if ( !pViewData )
309 return;
311 ScDocument& rDoc = pViewData->GetDocument();
313 for (sal_uInt16 j = nStartField; j < nSortKeyCount; ++j)
315 m_aSortWin.m_aSortKeyItems[j]->m_xLabel->set_label(aSortData.bByRow ? aStrColumn : aStrRow);
316 m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->clear();
317 m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->freeze();
318 m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->append_text(aStrUndefined);
321 SCCOL nFirstSortCol = aSortData.nCol1;
322 SCROW nFirstSortRow = aSortData.nRow1;
323 SCTAB nTab = pViewData->GetTabNo();
324 sal_uInt16 i = 1;
325 nFieldArr.clear();
326 nFieldArr.push_back(0);
328 if ( aSortData.bByRow )
330 OUString aFieldName;
331 SCCOL nMaxCol = rDoc.ClampToAllocatedColumns(nTab, aSortData.nCol2);
332 SCCOL col;
334 for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS(rDoc.GetSheetLimits()); col++ )
336 aFieldName = rDoc.GetString(col, nFirstSortRow, nTab);
337 if ( !aSortData.bHasHeader || aFieldName.isEmpty() )
338 aFieldName = ScColToAlpha( col );
339 nFieldArr.push_back( col );
341 for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
342 m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
344 i++;
347 else
349 OUString aFieldName;
350 SCROW nMaxRow = aSortData.nRow2;
351 SCROW row;
353 for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS(rDoc.GetSheetLimits()); row++ )
355 aFieldName = rDoc.GetString(nFirstSortCol, row, nTab);
356 if ( !aSortData.bHasHeader || aFieldName.isEmpty() )
357 aFieldName = OUString::number( row+1);
358 nFieldArr.push_back( row );
360 for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
361 m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->insert_text(i, aFieldName);
363 i++;
367 for (sal_uInt16 j=nStartField; j < nSortKeyCount; ++j)
369 m_aSortWin.m_aSortKeyItems[j]->m_xLbSort->thaw();
372 nFieldCount = i;
375 sal_uInt16 ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
377 sal_uInt16 nFieldPos = 0;
378 bool bFound = false;
380 for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
382 if ( nFieldArr[n] == nField )
384 nFieldPos = n;
385 bFound = true;
389 return nFieldPos;
392 void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )
394 // Extend local SortParam copy
395 const ScSortKeyState atempKeyState = { 0, false, true, ScColorSortMode::None, Color() };
396 aSortData.maKeyState.push_back( atempKeyState );
398 // Add Sort Key Item
399 ++nSortKeyCount;
400 AddSortKey( nSortKeyCount );
401 m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->connect_changed(
402 LINK( this, ScTabPageSortFields, SelectHdl ) );
404 FillFieldLists( nItem );
406 // Set Status
407 m_aSortWin.m_aSortKeyItems[nItem]->m_xBtnUp->set_active(true);
408 m_aSortWin.m_aSortKeyItems[nItem]->m_xLbSort->set_active(0);
411 // Handler:
413 IMPL_LINK_NOARG(ScTabPageSortFields, SortDirHdl, weld::Toggleable&, void)
415 if ( (m_xBtnTopDown->get_active() != aSortData.bByRow) || (m_xBtnHeader->get_active() != aSortData.bHasHeader))
417 if (m_xBtnTopDown->get_active())
418 m_xBtnHeader->set_label(aStrColLabel);
419 else
420 m_xBtnHeader->set_label(aStrRowLabel);
422 aSortData.bByRow = m_xBtnTopDown->get_active();
423 aSortData.bHasHeader = m_xBtnHeader->get_active();
425 // remember selection
426 std::vector<sal_uInt16> nCurSel;
427 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
428 nCurSel.push_back( m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->get_active() );
430 FillFieldLists(0);
432 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
433 m_aSortWin.m_aSortKeyItems[i]->m_xLbSort->set_active(nCurSel[i]);
437 IMPL_LINK( ScTabPageSortFields, SelectHdl, weld::ComboBox&, rLb, void )
439 OUString aSelEntry = rLb.get_active_text();
440 ScSortKeyItems::iterator pIter;
442 // If last listbox is enabled add one item
443 if (m_aSortWin.m_aSortKeyItems.back()->m_xLbSort.get() == &rLb)
445 if ( aSelEntry != aStrUndefined )
447 SetLastSortKey( nSortKeyCount );
448 return;
452 // Find selected listbox
453 pIter = std::find_if(m_aSortWin.m_aSortKeyItems.begin(), m_aSortWin.m_aSortKeyItems.end(),
454 [&rLb](const ScSortKeyItems::value_type& rItem) { return rItem->m_xLbSort.get() == &rLb; });
456 if (pIter == m_aSortWin.m_aSortKeyItems.end())
457 return;
459 // If not selecting the last Listbox, modify the succeeding ones
460 ++pIter;
461 if ( std::distance(m_aSortWin.m_aSortKeyItems.begin(), pIter) >= nSortKeyCount )
462 return;
464 if ( aSelEntry == aStrUndefined )
466 for ( ; pIter != m_aSortWin.m_aSortKeyItems.end(); ++pIter )
468 (*pIter)->m_xLbSort->set_active(0);
470 (*pIter)->DisableField();
473 else
475 (*pIter)->EnableField();
479 IMPL_LINK_NOARG(ScTabPageSortFields, ScrollToEndHdl, Timer*, void)
481 m_xScrolledWindow->vadjustment_set_value(m_xScrolledWindow->vadjustment_get_upper());
484 void ScTabPageSortFields::AddSortKey( sal_uInt16 nItem )
486 m_aSortWin.AddSortKey(nItem);
487 m_aIdle.Start();
490 // Sort option Tab Page:
492 ScTabPageSortOptions::ScTabPageSortOptions(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rArgSet)
493 : SfxTabPage(pPage, pController, u"modules/scalc/ui/sortoptionspage.ui"_ustr, u"SortOptionsPage"_ustr, &rArgSet)
494 , aStrUndefined(ScResId(SCSTR_UNDEFINED))
495 , aStrCommentsRowLabel(ScResId(SCSTR_NOTES_ROW_LABEL))
496 , aStrCommentsColLabel(ScResId(SCSTR_NOTES_COL_LABEL))
497 , aStrImgRowLabel(ScResId(SCSTR_IMAGES_ROW_LABEL))
498 , aStrImgColLabel(ScResId(SCSTR_IMAGES_COL_LABEL))
499 , nWhichSort(rArgSet.GetPool()->GetWhichIDFromSlotID(SID_SORT))
500 , aSortData(rArgSet.Get(nWhichSort).GetSortData())
501 , pViewData(nullptr)
502 , pDoc(nullptr)
503 , m_xBtnCase(m_xBuilder->weld_check_button(u"case"_ustr))
504 , m_xBtnFormats(m_xBuilder->weld_check_button(u"formats"_ustr))
505 , m_xBtnNaturalSort(m_xBuilder->weld_check_button(u"naturalsort"_ustr))
506 , m_xBtnCopyResult(m_xBuilder->weld_check_button(u"copyresult"_ustr))
507 , m_xLbOutPos(m_xBuilder->weld_combo_box(u"outarealb"_ustr))
508 , m_xEdOutPos(m_xBuilder->weld_entry(u"outareaed"_ustr))
509 , m_xBtnSortUser(m_xBuilder->weld_check_button(u"sortuser"_ustr))
510 , m_xLbSortUser(m_xBuilder->weld_combo_box(u"sortuserlb"_ustr))
511 , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"language"_ustr)))
512 , m_xFtAlgorithm(m_xBuilder->weld_label(u"algorithmft"_ustr))
513 , m_xLbAlgorithm(m_xBuilder->weld_combo_box(u"algorithmlb"_ustr))
514 , m_xBtnIncComments(m_xBuilder->weld_check_button(u"includenotes"_ustr))
515 , m_xBtnIncImages(m_xBuilder->weld_check_button(u"includeimages"_ustr))
517 m_xLbSortUser->set_size_request(m_xLbSortUser->get_approximate_digit_width() * 50, -1);
518 m_xLbSortUser->set_accessible_description(ScResId(STR_A11Y_DESC_SORTUSER));
519 Init();
520 SetExchangeSupport();
523 void ScTabPageSortOptions::Init()
525 // CollatorResource has user-visible names for sort algorithms
526 m_xColRes.reset(new CollatorResource);
528 //! use CollatorWrapper from document?
529 m_oColWrap.emplace(comphelper::getProcessComponentContext());
531 const ScSortItem& rSortItem = GetItemSet().Get( nWhichSort );
533 m_xLbOutPos->connect_changed( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
534 m_xBtnCopyResult->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
535 m_xBtnSortUser->connect_toggled( LINK( this, ScTabPageSortOptions, EnableHdl ) );
536 m_xLbLanguage->connect_changed( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
538 pViewData = rSortItem.GetViewData();
539 pDoc = pViewData ? &pViewData->GetDocument() : nullptr;
541 OSL_ENSURE( pViewData, "ViewData not found! :-/" );
543 if ( pViewData && pDoc )
545 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
547 m_xLbOutPos->clear();
548 m_xLbOutPos->append_text(aStrUndefined);
549 m_xLbOutPos->set_sensitive(false);
551 ScAreaNameIterator aIter( *pDoc );
552 OUString aName;
553 ScRange aRange;
554 while ( aIter.Next( aName, aRange ) )
556 OUString aRefStr(aRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDoc, eConv));
557 m_xLbOutPos->append(aRefStr, aName);
560 m_xLbOutPos->set_active(0);
561 m_xEdOutPos->set_text(OUString());
564 m_xBtnIncComments->set_label(aStrCommentsColLabel);
565 m_xBtnIncImages->set_label(aStrImgColLabel);
567 FillUserSortListBox();
569 // get available languages
571 m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
572 m_xLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
575 std::unique_ptr<SfxTabPage> ScTabPageSortOptions::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rArgSet)
577 return std::make_unique<ScTabPageSortOptions>(pPage, pController, *rArgSet);
580 void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
582 if ( aSortData.bUserDef )
584 m_xBtnSortUser->set_active(true);
585 m_xLbSortUser->set_sensitive(true);
586 m_xLbSortUser->set_active(aSortData.nUserIndex);
588 else
590 m_xBtnSortUser->set_active(false);
591 m_xLbSortUser->set_sensitive(false);
592 m_xLbSortUser->set_active(0);
595 m_xBtnCase->set_active( aSortData.bCaseSens );
596 m_xBtnFormats->set_active( aSortData.aDataAreaExtras.mbCellFormats );
597 m_xBtnNaturalSort->set_active( aSortData.bNaturalSort );
598 m_xBtnIncComments->set_active( aSortData.aDataAreaExtras.mbCellNotes );
599 m_xBtnIncImages->set_active( aSortData.aDataAreaExtras.mbCellDrawObjects );
601 LanguageType eLang = LanguageTag::convertToLanguageType( aSortData.aCollatorLocale, false);
602 if ( eLang == LANGUAGE_DONTKNOW )
603 eLang = LANGUAGE_SYSTEM;
604 m_xLbLanguage->set_active_id(eLang);
605 FillAlgor(); // get algorithms, select default
606 if ( !aSortData.aCollatorAlgorithm.isEmpty() )
607 m_xLbAlgorithm->set_active_text(m_xColRes->GetTranslation(aSortData.aCollatorAlgorithm));
609 if ( pDoc && !aSortData.bInplace )
611 ScRefFlags nFormat = (aSortData.nDestTab != pViewData->GetTabNo())
612 ? ScRefFlags::RANGE_ABS_3D
613 : ScRefFlags::RANGE_ABS;
615 theOutPos.Set( aSortData.nDestCol,
616 aSortData.nDestRow,
617 aSortData.nDestTab );
619 OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
620 m_xBtnCopyResult->set_active(true);
621 m_xLbOutPos->set_sensitive(true);
622 m_xEdOutPos->set_sensitive(true);
623 m_xEdOutPos->set_text( aStr );
624 EdOutPosModHdl();
625 m_xEdOutPos->grab_focus();
626 m_xEdOutPos->select_region(0, -1);
628 else
630 m_xBtnCopyResult->set_active( false );
631 m_xLbOutPos->set_sensitive(false);
632 m_xEdOutPos->set_sensitive(false);
633 m_xEdOutPos->set_text( OUString() );
637 bool ScTabPageSortOptions::FillItemSet( SfxItemSet* rArgSet )
639 // Create local copy of ScParam
640 ScSortParam aNewSortData = aSortData;
642 const SfxItemSet* pExample = GetDialogExampleSet();
643 if (pExample)
645 if (const ScSortItem* pSortItem = pExample->GetItemIfSet(nWhichSort))
646 aNewSortData = pSortItem->GetSortData();
648 aNewSortData.bCaseSens = m_xBtnCase->get_active();
649 aNewSortData.bNaturalSort = m_xBtnNaturalSort->get_active();
650 aNewSortData.aDataAreaExtras.mbCellNotes = m_xBtnIncComments->get_active();
651 aNewSortData.aDataAreaExtras.mbCellDrawObjects = m_xBtnIncImages->get_active();
652 aNewSortData.aDataAreaExtras.mbCellFormats = m_xBtnFormats->get_active();
653 aNewSortData.bInplace = !m_xBtnCopyResult->get_active();
654 aNewSortData.nDestCol = theOutPos.Col();
655 aNewSortData.nDestRow = theOutPos.Row();
656 aNewSortData.nDestTab = theOutPos.Tab();
657 aNewSortData.bUserDef = m_xBtnSortUser->get_active();
658 aNewSortData.nUserIndex = (m_xBtnSortUser->get_active())
659 ? m_xLbSortUser->get_active()
660 : 0;
662 // get locale
663 LanguageType eLang = m_xLbLanguage->get_active_id();
664 aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);
666 // get algorithm
667 OUString sAlg;
668 if ( eLang != LANGUAGE_SYSTEM )
670 uno::Sequence<OUString> aAlgos = m_oColWrap->listCollatorAlgorithms(
671 aNewSortData.aCollatorLocale );
672 const int nSel = m_xLbAlgorithm->get_active();
673 if ( nSel < aAlgos.getLength() )
674 sAlg = aAlgos[nSel];
676 aNewSortData.aCollatorAlgorithm = sAlg;
678 rArgSet->Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
680 return true;
683 // for data exchange without dialogue detour:
684 void ScTabPageSortOptions::ActivatePage( const SfxItemSet& rSet )
686 // Refresh local copy with shared data
687 aSortData = rSet.Get( SCITEM_SORTDATA ).GetSortData();
688 ScSortDlg* pDlg = static_cast<ScSortDlg*>(GetDialogController());
689 if (!pDlg)
690 return;
692 if (aSortData.bByRow)
694 m_xBtnIncComments->set_label(aStrCommentsRowLabel);
695 m_xBtnIncImages->set_label(aStrImgRowLabel);
697 else
699 m_xBtnIncComments->set_label(aStrCommentsColLabel);
700 m_xBtnIncImages->set_label(aStrImgColLabel);
704 DeactivateRC ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )
706 bool bPosInputOk = true;
708 if ( m_xBtnCopyResult->get_active() )
710 OUString thePosStr = m_xEdOutPos->get_text();
711 ScAddress thePos;
712 sal_Int32 nColonPos = thePosStr.indexOf( ':' );
714 if ( -1 != nColonPos )
715 thePosStr = thePosStr.copy( 0, nColonPos );
717 if ( pViewData )
719 // visible table is default for input without table
720 // must be changed to GetRefTabNo when sorting has RefInput!
721 thePos.SetTab( pViewData->GetTabNo() );
724 ScRefFlags nResult = thePos.Parse( thePosStr, *pDoc, pDoc->GetAddressConvention() );
726 bPosInputOk = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID;
728 if ( !bPosInputOk )
730 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
731 VclMessageType::Warning, VclButtonsType::Ok,
732 ScResId(STR_INVALID_TABREF)));
733 xBox->run();
734 m_xEdOutPos->grab_focus();
735 m_xEdOutPos->select_region(0, -1);
736 theOutPos.Set(0,0,0);
738 else
740 m_xEdOutPos->set_text(thePosStr);
741 theOutPos = thePos;
745 if ( pSetP && bPosInputOk )
746 FillItemSet( pSetP );
748 return bPosInputOk ? DeactivateRC::LeavePage : DeactivateRC::KeepPage;
751 void ScTabPageSortOptions::FillUserSortListBox()
753 ScUserList& rUserLists = ScGlobal::GetUserList();
755 m_xLbSortUser->clear();
756 size_t nCount = rUserLists.size();
757 for (size_t i=0; i<nCount; ++i)
758 m_xLbSortUser->append_text(rUserLists[i].GetString());
761 // Handler:
763 IMPL_LINK( ScTabPageSortOptions, EnableHdl, weld::Toggleable&, rButton, void )
765 if (&rButton == m_xBtnCopyResult.get())
767 if (rButton.get_active())
769 m_xLbOutPos->set_sensitive(true);
770 m_xEdOutPos->set_sensitive(true);
771 m_xEdOutPos->grab_focus();
773 else
775 m_xLbOutPos->set_sensitive(false);
776 m_xEdOutPos->set_sensitive(false);
779 else if (&rButton == m_xBtnSortUser.get())
781 if (rButton.get_active())
783 m_xLbSortUser->set_sensitive(true);
784 m_xLbSortUser->grab_focus();
786 else
787 m_xLbSortUser->set_sensitive(false);
791 IMPL_LINK(ScTabPageSortOptions, SelOutPosHdl, weld::ComboBox&, rLb, void)
793 if (&rLb == m_xLbOutPos.get())
795 OUString aString;
796 const int nSelPos = m_xLbOutPos->get_active();
798 if (nSelPos > 0)
799 aString = m_xLbOutPos->get_id(nSelPos);
801 m_xEdOutPos->set_text(aString);
805 void ScTabPageSortOptions::EdOutPosModHdl()
807 OUString theCurPosStr = m_xEdOutPos->get_text();
808 ScRefFlags nResult = ScAddress().Parse( theCurPosStr, *pDoc, pDoc->GetAddressConvention() );
810 if ( (nResult & ScRefFlags::VALID) != ScRefFlags::VALID )
811 return;
813 bool bFound = false;
814 sal_Int32 i = 0;
815 const int nCount = m_xLbOutPos->get_count();
817 for ( i=2; i<nCount && !bFound; i++ )
819 OUString aStr = m_xLbOutPos->get_id(i);
820 bFound = (theCurPosStr == aStr);
823 if ( bFound )
824 m_xLbOutPos->set_active(--i);
825 else
826 m_xLbOutPos->set_active(0);
829 void ScTabPageSortOptions::FillAlgor()
831 tools::Long nCount = 0;
833 m_xLbAlgorithm->freeze();
834 m_xLbAlgorithm->clear();
836 LanguageType eLang = m_xLbLanguage->get_active_id();
837 if ( eLang == LANGUAGE_SYSTEM )
839 // for LANGUAGE_SYSTEM no algorithm can be selected because
840 // it wouldn't necessarily exist for other languages
841 // -> leave list box empty if LANGUAGE_SYSTEM is selected
842 m_xFtAlgorithm->set_sensitive( false ); // nothing to select
843 m_xLbAlgorithm->set_sensitive( false ); // nothing to select
845 else
847 lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
848 const uno::Sequence<OUString> aAlgos = m_oColWrap->listCollatorAlgorithms( aLocale );
850 nCount = aAlgos.getLength();
851 for (const OUString& sAlg : aAlgos)
853 OUString sUser = m_xColRes->GetTranslation( sAlg );
854 m_xLbAlgorithm->append_text(sUser);
858 m_xLbAlgorithm->thaw();
860 m_xLbAlgorithm->set_active(nCount ? 0 : -1); // first entry is default
861 m_xFtAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
862 m_xLbAlgorithm->set_sensitive(nCount > 1); // enable only if there is a choice
865 IMPL_LINK_NOARG(ScTabPageSortOptions, FillAlgorHdl, weld::ComboBox&, void)
867 FillAlgor();
870 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */