1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
36 #include <userlist.hxx>
37 #include <rangeutl.hxx>
38 #include <scresid.hxx>
40 #include <strings.hrc>
41 #include <globstr.hrc>
43 #include <sortkeydlg.hxx>
45 #include <sortdlg.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
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() ),
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);
104 m_aIdle
.SetInvokeHandler(LINK(this, ScTabPageSortFields
, ScrollToEndHdl
));
106 SetExchangeSupport();
109 ScTabPageSortFields::~ScTabPageSortFields()
111 m_aSortWin
.m_aSortKeyItems
.clear();
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;
122 ScDBCollection
* pDBColl
= pDoc
->GetDBCollection();
123 const SCTAB nCurTab
= pViewData
->GetTabNo();
127 = pDBColl
->GetDBAtArea( nCurTab
,
128 aSortData
.nCol1
, aSortData
.nRow1
,
129 aSortData
.nCol2
, aSortData
.nRow2
);
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
++ )
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)
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
++ )
179 m_aSortWin
.m_aSortKeyItems
[i
]->m_xLbSort
->connect_changed( LINK( this,
180 ScTabPageSortFields
, SelectHdl
) );
182 nSortKeyCount
= aSortData
.GetSortKeyCount();
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);
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();
208 m_aSortWin
.m_aSortKeyItems
[i
]->EnableField();
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();
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();
278 for ( sal_uInt16 i
=0; i
<nSortKeyCount
; i
++ )
279 aNewSortData
.maKeyState
[i
].bDoSort
= false;
282 rArgSet
->Put( ScSortItem( SCITEM_SORTDATA
, nullptr, &aNewSortData
) );
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
)
301 FillItemSet( pSetP
);
303 return DeactivateRC::LeavePage
;
306 void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField
)
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();
326 nFieldArr
.push_back(0);
328 if ( aSortData
.bByRow
)
331 SCCOL nMaxCol
= rDoc
.ClampToAllocatedColumns(nTab
, aSortData
.nCol2
);
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
);
350 SCROW nMaxRow
= aSortData
.nRow2
;
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
);
367 for (sal_uInt16 j
=nStartField
; j
< nSortKeyCount
; ++j
)
369 m_aSortWin
.m_aSortKeyItems
[j
]->m_xLbSort
->thaw();
375 sal_uInt16
ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField
)
377 sal_uInt16 nFieldPos
= 0;
380 for ( sal_uInt16 n
=1; n
<nFieldCount
&& !bFound
; n
++ )
382 if ( nFieldArr
[n
] == nField
)
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
);
400 AddSortKey( nSortKeyCount
);
401 m_aSortWin
.m_aSortKeyItems
[nItem
]->m_xLbSort
->connect_changed(
402 LINK( this, ScTabPageSortFields
, SelectHdl
) );
404 FillFieldLists( nItem
);
407 m_aSortWin
.m_aSortKeyItems
[nItem
]->m_xBtnUp
->set_active(true);
408 m_aSortWin
.m_aSortKeyItems
[nItem
]->m_xLbSort
->set_active(0);
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
);
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() );
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
);
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())
459 // If not selecting the last Listbox, modify the succeeding ones
461 if ( std::distance(m_aSortWin
.m_aSortKeyItems
.begin(), pIter
) >= nSortKeyCount
)
464 if ( aSelEntry
== aStrUndefined
)
466 for ( ; pIter
!= m_aSortWin
.m_aSortKeyItems
.end(); ++pIter
)
468 (*pIter
)->m_xLbSort
->set_active(0);
470 (*pIter
)->DisableField();
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
);
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())
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
));
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
);
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
);
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
,
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
);
625 m_xEdOutPos
->grab_focus();
626 m_xEdOutPos
->select_region(0, -1);
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();
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()
663 LanguageType eLang
= m_xLbLanguage
->get_active_id();
664 aNewSortData
.aCollatorLocale
= LanguageTag::convertToLocale( eLang
, false);
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() )
676 aNewSortData
.aCollatorAlgorithm
= sAlg
;
678 rArgSet
->Put( ScSortItem( SCITEM_SORTDATA
, &aNewSortData
) );
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());
692 if (aSortData
.bByRow
)
694 m_xBtnIncComments
->set_label(aStrCommentsRowLabel
);
695 m_xBtnIncImages
->set_label(aStrImgRowLabel
);
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();
712 sal_Int32 nColonPos
= thePosStr
.indexOf( ':' );
714 if ( -1 != nColonPos
)
715 thePosStr
= thePosStr
.copy( 0, nColonPos
);
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
;
730 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetFrameWeld(),
731 VclMessageType::Warning
, VclButtonsType::Ok
,
732 ScResId(STR_INVALID_TABREF
)));
734 m_xEdOutPos
->grab_focus();
735 m_xEdOutPos
->select_region(0, -1);
736 theOutPos
.Set(0,0,0);
740 m_xEdOutPos
->set_text(thePosStr
);
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());
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();
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();
787 m_xLbSortUser
->set_sensitive(false);
791 IMPL_LINK(ScTabPageSortOptions
, SelOutPosHdl
, weld::ComboBox
&, rLb
, void)
793 if (&rLb
== m_xLbOutPos
.get())
796 const int nSelPos
= m_xLbOutPos
->get_active();
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
)
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
);
824 m_xLbOutPos
->set_active(--i
);
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
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)
870 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */