Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / dbgui / tpsort.cxx
blob3b5d4023b375398217cc5873b14ccc9703352707
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/msgbox.hxx>
23 #include <i18nlangtag/languagetag.hxx>
24 #include <svtools/collatorres.hxx>
25 #include <unotools/collatorwrapper.hxx>
26 #include <unotools/localedatawrapper.hxx>
27 #include <comphelper/processfactory.hxx>
29 #include "scitems.hxx"
30 #include "uiitems.hxx"
31 #include "viewdata.hxx"
32 #include "document.hxx"
33 #include "global.hxx"
34 #include "globalnames.hxx"
35 #include "dbdata.hxx"
36 #include "userlist.hxx"
37 #include "rangeutl.hxx"
38 #include "scresid.hxx"
39 #include "sc.hrc"
40 #include "globstr.hrc"
42 #include "sortkeydlg.hxx"
44 #include "sortdlg.hxx"
46 #include "tpsort.hxx"
48 using namespace com::sun::star;
51 * Since the settings on the second Tab Page (Options) effects
52 * the first Tab Page, there must be a way for it to communicate with the
53 * other Page.
55 * At the moment this problem is solved through using two data members of the
56 * Tab Pages. If a page is enabled / disabled, it compares this data member
57 * with its own state (-> Activate() / Deactivate()).
59 * In the meantime the class SfxTabPage offers the following method:
61 * virtual sal_Bool HasExchangeSupport() const; -> return sal_True;
62 * virtual void ActivatePage(const SfxItemSet &);
63 * virtual int DeactivatePage(SfxItemSet * = 0);
65 * This still needs to be changed!
68 // Sort Criteria Tab page
70 ScTabPageSortFields::ScTabPageSortFields(vcl::Window* pParent,
71 const SfxItemSet& rArgSet)
72 : SfxTabPage(pParent, "SortCriteriaPage",
73 "modules/scalc/ui/sortcriteriapage.ui", &rArgSet)
76 aStrUndefined ( SC_RESSTR( SCSTR_UNDEFINED ) ),
77 aStrColumn ( SC_RESSTR( SCSTR_COLUMN ) ),
78 aStrRow ( SC_RESSTR( SCSTR_ROW ) ),
80 nWhichSort ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
81 pDlg ( static_cast<ScSortDlg*>(GetParentDialog()) ),
82 pViewData ( nullptr ),
83 aSortData ( static_cast<const ScSortItem&>(
84 rArgSet.Get( nWhichSort )).
85 GetSortData() ),
86 nFieldCount ( 0 ),
87 nSortKeyCount ( DEFSORT ),
88 bHasHeader ( false ),
89 bSortByRows ( false ),
90 maSortKeyCtrl ( this, maSortKeyItems )
92 Init();
93 SetExchangeSupport();
96 ScTabPageSortFields::~ScTabPageSortFields()
98 disposeOnce();
101 void ScTabPageSortFields::dispose()
103 pDlg.clear();
104 maSortKeyItems.clear();
105 maSortKeyCtrl.dispose();
106 SfxTabPage::dispose();
109 void ScTabPageSortFields::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
111 SfxTabPage::SetPosSizePixel(rAllocPos, rAllocation);
112 maSortKeyCtrl.setScrollRange();
115 void ScTabPageSortFields::SetSizePixel(const Size& rAllocation)
117 SfxTabPage::SetSizePixel(rAllocation);
118 maSortKeyCtrl.setScrollRange();
121 void ScTabPageSortFields::SetPosPixel(const Point& rAllocPos)
123 SfxTabPage::SetPosPixel(rAllocPos);
124 maSortKeyCtrl.setScrollRange();
127 void ScTabPageSortFields::Init()
129 const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
130 GetItemSet().Get( nWhichSort ));
132 pViewData = rSortItem.GetViewData();
133 OSL_ENSURE( pViewData, "ViewData not found!" );
135 nFieldArr.push_back( 0 );
136 nFirstCol = 0;
137 nFirstRow = 0;
139 // Create three sort key dialogs by default
140 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
142 maSortKeyCtrl.AddSortKey(i+1);
143 maSortKeyItems[i]->m_pLbSort->SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
147 VclPtr<SfxTabPage> ScTabPageSortFields::Create( vcl::Window* pParent,
148 const SfxItemSet* rArgSet )
150 return VclPtr<ScTabPageSortFields>::Create( pParent, *rArgSet );
153 void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
155 bSortByRows = aSortData.bByRow;
156 bHasHeader = aSortData.bHasHeader;
158 if ( maSortKeyItems[0]->m_pLbSort->GetEntryCount() == 0 )
159 FillFieldLists(0);
161 // ListBox selection:
162 if (!aSortData.maKeyState.empty() && aSortData.maKeyState[0].bDoSort)
164 // Make sure that the all sort keys are reset
165 for ( sal_uInt16 i=nSortKeyCount; i<aSortData.GetSortKeyCount(); i++ )
167 maSortKeyCtrl.AddSortKey(i+1);
168 maSortKeyItems[i]->m_pLbSort->SetSelectHdl( LINK( this,
169 ScTabPageSortFields, SelectHdl ) );
171 nSortKeyCount = aSortData.GetSortKeyCount();
172 FillFieldLists(0);
174 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
176 if (aSortData.maKeyState[i].bDoSort )
178 maSortKeyItems[i]->m_pLbSort->SelectEntryPos( GetFieldSelPos(
179 aSortData.maKeyState[i].nField ) );
180 (aSortData.maKeyState[i].bAscending)
181 ? maSortKeyItems[i]->m_pBtnUp->Check()
182 : maSortKeyItems[i]->m_pBtnDown->Check();
184 else
186 maSortKeyItems[i]->m_pLbSort->SelectEntryPos( 0 ); // Select none
187 maSortKeyItems[i]->m_pBtnUp->Check();
191 // Enable or disable field depending on preceding Listbox selection
192 maSortKeyItems[0]->EnableField();
193 for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
194 if ( maSortKeyItems[i - 1]->m_pLbSort->GetSelectEntryPos() == 0 )
195 maSortKeyItems[i]->DisableField();
196 else
197 maSortKeyItems[i]->EnableField();
199 else
201 SCCOL nCol = pViewData->GetCurX();
203 if( nCol < aSortData.nCol1 )
204 nCol = aSortData.nCol1;
205 else if( nCol > aSortData.nCol2 )
206 nCol = aSortData.nCol2;
208 sal_uInt16 nSort1Pos = nCol - aSortData.nCol1+1;
210 maSortKeyItems[0]->m_pLbSort->SelectEntryPos( nSort1Pos );
211 for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
212 maSortKeyItems[i]->m_pLbSort->SelectEntryPos( 0 );
214 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
215 maSortKeyItems[i]->m_pBtnUp->Check();
217 maSortKeyItems[0]->EnableField();
218 maSortKeyItems[1]->EnableField();
219 for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
220 maSortKeyItems[i]->DisableField();
223 if ( pDlg )
225 pDlg->SetByRows ( bSortByRows );
226 pDlg->SetHeaders( bHasHeader );
229 // Make sure that there is always a last undefined sort key
230 if ( maSortKeyItems[nSortKeyCount - 1]->m_pLbSort->GetSelectEntryPos() > 0 )
231 SetLastSortKey( nSortKeyCount );
234 bool ScTabPageSortFields::FillItemSet( SfxItemSet* rArgSet )
236 ScSortParam aNewSortData = aSortData;
238 if (pDlg)
240 const SfxItemSet* pExample = pDlg->GetExampleSet();
241 const SfxPoolItem* pItem;
242 if ( pExample && pExample->GetItemState( nWhichSort, true, &pItem ) == SfxItemState::SET )
244 ScSortParam aTempData = static_cast<const ScSortItem*>(pItem)->GetSortData();
245 aTempData.maKeyState = aNewSortData.maKeyState;
246 aNewSortData = aTempData;
249 std::vector<sal_Int32> nSortPos;
251 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
253 nSortPos.push_back( maSortKeyItems[i]->m_pLbSort->GetSelectEntryPos() );
255 if ( nSortPos[i] == LISTBOX_ENTRY_NOTFOUND ) nSortPos[i] = 0;
258 if( nSortKeyCount >= aNewSortData.GetSortKeyCount() )
259 aNewSortData.maKeyState.resize(nSortKeyCount);
261 if ( nSortPos[0] > 0 )
263 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
264 aNewSortData.maKeyState[i].bDoSort = (nSortPos[i] > 0);
266 // If the "OK" was selected on the Options page while the sort
267 // direction was changed, then the first field (i.e. nFieldArr[0])
268 // of the respective direction is chosen as the sorting criterion:
269 if ( pDlg && bSortByRows != pDlg->GetByRows() )
271 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
272 aNewSortData.maKeyState[i].nField = ( bSortByRows ?
273 static_cast<SCCOLROW>(nFirstRow) :
274 static_cast<SCCOLROW>(nFirstCol) );
276 else
278 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
279 aNewSortData.maKeyState[i].nField = nFieldArr[nSortPos[i]];
282 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
283 aNewSortData.maKeyState[i].bAscending = maSortKeyItems[i]->m_pBtnUp->IsChecked();
285 // bHasHeader is in ScTabPageSortOptions::FillItemSet, where it belongs
287 else
289 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
290 aNewSortData.maKeyState[i].bDoSort = false;
293 rArgSet->Put( ScSortItem( SCITEM_SORTDATA, nullptr, &aNewSortData ) );
295 return true;
298 // for data exchange without dialogue detour:
299 void ScTabPageSortFields::ActivatePage( const SfxItemSet& rSet )
301 // Refresh local copy with shared data
302 aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
303 if ( pDlg )
305 if ( bHasHeader != pDlg->GetHeaders()
306 || bSortByRows != pDlg->GetByRows() )
308 std::vector<sal_uInt16> nCurSel;
309 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
310 nCurSel.push_back( maSortKeyItems[i]->m_pLbSort->GetSelectEntryPos() );
312 bHasHeader = pDlg->GetHeaders();
313 bSortByRows = pDlg->GetByRows();
314 FillFieldLists(0);
316 for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
317 maSortKeyItems[i]->m_pLbSort->SelectEntryPos( nCurSel[i] );
322 SfxTabPage::sfxpg ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
324 if ( pDlg )
326 if ( bHasHeader != pDlg->GetHeaders() )
327 pDlg->SetHeaders( bHasHeader );
329 if ( bSortByRows != pDlg->GetByRows() )
330 pDlg->SetByRows( bSortByRows );
333 if ( pSetP )
334 FillItemSet( pSetP );
336 return SfxTabPage::LEAVE_PAGE;
339 void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
341 if ( pViewData )
343 ScDocument* pDoc = pViewData->GetDocument();
345 if ( pDoc )
347 for ( sal_uInt16 i=nStartField; i<nSortKeyCount; i++ )
349 maSortKeyItems[i]->m_pLbSort->Clear();
350 maSortKeyItems[i]->m_pLbSort->InsertEntry( aStrUndefined, 0 );
353 SCCOL nFirstSortCol = aSortData.nCol1;
354 SCROW nFirstSortRow = aSortData.nRow1;
355 SCTAB nTab = pViewData->GetTabNo();
356 sal_uInt16 i = 1;
357 nFieldArr.clear();
358 nFieldArr.push_back(0);
360 if ( bSortByRows )
362 OUString aFieldName;
363 SCCOL nMaxCol = aSortData.nCol2;
364 SCCOL col;
366 for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
368 aFieldName = pDoc->GetString(col, nFirstSortRow, nTab);
369 if ( !bHasHeader || aFieldName.isEmpty() )
371 aFieldName = ScGlobal::ReplaceOrAppend( aStrColumn, "%1", ScColToAlpha( col ));
373 nFieldArr.push_back( col );
375 for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
376 maSortKeyItems[j]->m_pLbSort->InsertEntry( aFieldName, i );
378 i++;
381 else
383 OUString aFieldName;
384 SCROW nMaxRow = aSortData.nRow2;
385 SCROW row;
387 for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS; row++ )
389 aFieldName = pDoc->GetString(nFirstSortCol, row, nTab);
390 if ( !bHasHeader || aFieldName.isEmpty() )
392 aFieldName = ScGlobal::ReplaceOrAppend( aStrRow, "%1", OUString::number( row+1));
394 nFieldArr.push_back( row );
396 for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
397 maSortKeyItems[j]->m_pLbSort->InsertEntry( aFieldName, i );
399 i++;
402 nFieldCount = i;
407 sal_uInt16 ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
409 sal_uInt16 nFieldPos = 0;
410 bool bFound = false;
412 for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
414 if ( nFieldArr[n] == nField )
416 nFieldPos = n;
417 bFound = true;
421 return nFieldPos;
424 void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )
426 // Extend local SortParam copy
427 const ScSortKeyState atempKeyState = { false, 0, true };
428 aSortData.maKeyState.push_back( atempKeyState );
430 // Add Sort Key Item
431 ++nSortKeyCount;
432 maSortKeyCtrl.AddSortKey( nSortKeyCount );
433 maSortKeyItems[nItem]->m_pLbSort->SetSelectHdl(
434 LINK( this, ScTabPageSortFields, SelectHdl ) );
436 FillFieldLists( nItem );
438 // Set Status
439 maSortKeyItems[nItem]->m_pBtnUp->Check();
440 maSortKeyItems[nItem]->m_pLbSort->SelectEntryPos( 0 );
443 // Handler:
445 IMPL_LINK_TYPED( ScTabPageSortFields, SelectHdl, ListBox&, rLb, void )
447 OUString aSelEntry = rLb.GetSelectEntry();
448 ScSortKeyItems::iterator pIter;
450 // If last listbox is enabled add one item
451 if ( maSortKeyItems.back()->m_pLbSort == &rLb )
452 if ( aSelEntry != aStrUndefined )
454 SetLastSortKey( nSortKeyCount );
455 return;
458 // Find selected listbox
459 for ( pIter = maSortKeyItems.begin(); pIter != maSortKeyItems.end(); ++pIter )
461 if ( (*pIter)->m_pLbSort == &rLb ) break;
464 if (pIter == maSortKeyItems.end())
465 return;
467 // If not selecting the last Listbox, modify the succeeding ones
468 ++pIter;
469 if ( std::distance(maSortKeyItems.begin(), pIter) < nSortKeyCount )
471 if ( aSelEntry == aStrUndefined )
473 for ( ; pIter != maSortKeyItems.end(); ++pIter )
475 (*pIter)->m_pLbSort->SelectEntryPos( 0 );
477 if ( (*pIter)->m_pFlSort->IsEnabled() )
478 (*pIter)->DisableField();
481 else
483 if ( !(*pIter)->m_pFlSort->IsEnabled() )
484 (*pIter)->EnableField();
489 // Sort option Tab Page:
491 ScTabPageSortOptions::ScTabPageSortOptions( vcl::Window* pParent,
492 const SfxItemSet& rArgSet )
493 : SfxTabPage(pParent, "SortOptionsPage",
494 "modules/scalc/ui/sortoptionspage.ui", &rArgSet)
495 , aStrRowLabel(SC_RESSTR(SCSTR_ROW_LABEL))
496 , aStrColLabel(SC_RESSTR(SCSTR_COL_LABEL))
497 , aStrUndefined(SC_RESSTR(SCSTR_UNDEFINED))
498 , nWhichSort(rArgSet.GetPool()->GetWhich(SID_SORT))
499 , aSortData(static_cast<const ScSortItem&>(rArgSet.Get(nWhichSort)).GetSortData())
500 , pViewData(nullptr)
501 , pDoc(nullptr)
502 , pDlg(static_cast<ScSortDlg*>(GetParentDialog()))
503 , pColRes( nullptr )
504 , pColWrap( nullptr )
506 get(m_pBtnCase, "case");
507 get(m_pBtnHeader, "header");
508 get(m_pBtnFormats, "formats");
509 get(m_pBtnNaturalSort, "naturalsort");
510 get(m_pBtnCopyResult, "copyresult");
511 get(m_pLbOutPos, "outarealb");
512 get(m_pEdOutPos, "outareaed");
513 get(m_pBtnSortUser, "sortuser");
514 get(m_pLbSortUser, "sortuserlb");
515 get(m_pFtAlgorithm, "algorithmft");
516 get(m_pLbAlgorithm, "algorithmlb");
517 get(m_pBtnTopDown, "topdown");
518 get(m_pBtnLeftRight, "leftright");
519 get(m_pLbLanguage, "language");
520 Init();
521 SetExchangeSupport();
523 m_pLbOutPos->SetAccessibleName(m_pBtnCopyResult->GetText());
524 m_pEdOutPos->SetAccessibleName(m_pBtnCopyResult->GetText());
525 m_pLbSortUser->SetAccessibleName(m_pBtnSortUser->GetText());
528 ScTabPageSortOptions::~ScTabPageSortOptions()
530 disposeOnce();
533 void ScTabPageSortOptions::dispose()
535 const sal_Int32 nEntries = m_pLbOutPos->GetEntryCount();
537 for ( sal_Int32 i=1; i<nEntries; ++i )
538 delete static_cast<OUString*>(m_pLbOutPos->GetEntryData( i ));
540 delete pColRes;
541 delete pColWrap; //! not if from document
542 m_pBtnCase.clear();
543 m_pBtnHeader.clear();
544 m_pBtnFormats.clear();
545 m_pBtnNaturalSort.clear();
546 m_pBtnCopyResult.clear();
547 m_pLbOutPos.clear();
548 m_pEdOutPos.clear();
549 m_pBtnSortUser.clear();
550 m_pLbSortUser.clear();
551 m_pLbLanguage.clear();
552 m_pFtAlgorithm.clear();
553 m_pLbAlgorithm.clear();
554 m_pBtnTopDown.clear();
555 m_pBtnLeftRight.clear();
556 pDlg.clear();
557 SfxTabPage::dispose();
560 void ScTabPageSortOptions::Init()
562 // CollatorResource has user-visible names for sort algorithms
563 pColRes = new CollatorResource();
565 //! use CollatorWrapper from document?
566 pColWrap = new CollatorWrapper( comphelper::getProcessComponentContext() );
568 const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
569 GetItemSet().Get( nWhichSort ));
571 m_pLbOutPos->SetSelectHdl ( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
572 m_pBtnCopyResult->SetClickHdl( LINK( this, ScTabPageSortOptions, EnableHdl ) );
573 m_pBtnSortUser->SetClickHdl ( LINK( this, ScTabPageSortOptions, EnableHdl ) );
574 m_pBtnTopDown->SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
575 m_pBtnLeftRight->SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
576 m_pLbLanguage->SetSelectHdl ( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
578 pViewData = rSortItem.GetViewData();
579 pDoc = pViewData ? pViewData->GetDocument() : nullptr;
581 OSL_ENSURE( pViewData, "ViewData not found! :-/" );
583 if ( pViewData && pDoc )
585 ScDBCollection* pDBColl = pDoc->GetDBCollection();
586 const SCTAB nCurTab = pViewData->GetTabNo();
587 OUString theDbName = STR_DB_LOCAL_NONAME;
588 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
590 m_pLbOutPos->Clear();
591 m_pLbOutPos->InsertEntry( aStrUndefined, 0 );
592 m_pLbOutPos->Disable();
594 ScAreaNameIterator aIter( pDoc );
595 OUString aName;
596 ScRange aRange;
597 while ( aIter.Next( aName, aRange ) )
599 const sal_Int32 nInsert = m_pLbOutPos->InsertEntry( aName );
601 OUString aRefStr(aRange.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDoc, eConv));
602 m_pLbOutPos->SetEntryData( nInsert, new OUString( aRefStr ) );
605 m_pLbOutPos->SelectEntryPos( 0 );
606 m_pEdOutPos->SetText( EMPTY_OUSTRING );
608 // Check whether the field that is passed on is a database field:
610 ScAddress aScAddress( aSortData.nCol1, aSortData.nRow1, nCurTab );
611 OUString theArea =
612 ScRange( aScAddress,
613 ScAddress( aSortData.nCol2, aSortData.nRow2, nCurTab )
614 ).Format(ScRefFlags::RANGE_ABS, pDoc, eConv);
616 if ( pDBColl )
618 ScDBData* pDBData
619 = pDBColl->GetDBAtArea( nCurTab,
620 aSortData.nCol1, aSortData.nRow1,
621 aSortData.nCol2, aSortData.nRow2 );
622 if ( pDBData )
624 theDbName = pDBData->GetName();
625 m_pBtnHeader->Check( pDBData->HasHeader() );
629 theArea += " (" + theDbName + ")";
631 m_pBtnHeader->SetText( aStrColLabel );
634 FillUserSortListBox();
636 // get available languages
638 m_pLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
639 m_pLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
642 VclPtr<SfxTabPage> ScTabPageSortOptions::Create( vcl::Window* pParent,
643 const SfxItemSet* rArgSet )
645 return VclPtr<ScTabPageSortOptions>::Create( pParent, *rArgSet );
648 void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
650 if ( aSortData.bUserDef )
652 m_pBtnSortUser->Check();
653 m_pLbSortUser->Enable();
654 m_pLbSortUser->SelectEntryPos( aSortData.nUserIndex );
656 else
658 m_pBtnSortUser->Check( false );
659 m_pLbSortUser->Disable();
660 m_pLbSortUser->SelectEntryPos( 0 );
663 m_pBtnCase->Check ( aSortData.bCaseSens );
664 m_pBtnFormats->Check ( aSortData.bIncludePattern );
665 m_pBtnHeader->Check ( aSortData.bHasHeader );
666 m_pBtnNaturalSort->Check ( aSortData.bNaturalSort );
668 if ( aSortData.bByRow )
670 m_pBtnTopDown->Check();
671 m_pBtnHeader->SetText( aStrColLabel );
673 else
675 m_pBtnLeftRight->Check();
676 m_pBtnHeader->SetText( aStrRowLabel );
679 LanguageType eLang = LanguageTag::convertToLanguageType( aSortData.aCollatorLocale, false);
680 if ( eLang == LANGUAGE_DONTKNOW )
681 eLang = LANGUAGE_SYSTEM;
682 m_pLbLanguage->SelectLanguage( eLang );
683 FillAlgorHdl(*m_pLbLanguage.get()); // get algorithms, select default
684 if ( !aSortData.aCollatorAlgorithm.isEmpty() )
685 m_pLbAlgorithm->SelectEntry( pColRes->GetTranslation( aSortData.aCollatorAlgorithm ) );
687 if ( pDoc && !aSortData.bInplace )
689 ScRefFlags nFormat = (aSortData.nDestTab != pViewData->GetTabNo())
690 ? ScRefFlags::RANGE_ABS_3D
691 : ScRefFlags::RANGE_ABS;
693 theOutPos.Set( aSortData.nDestCol,
694 aSortData.nDestRow,
695 aSortData.nDestTab );
697 OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
698 m_pBtnCopyResult->Check();
699 m_pLbOutPos->Enable();
700 m_pEdOutPos->Enable();
701 m_pEdOutPos->SetText( aStr );
702 EdOutPosModHdl(m_pEdOutPos);
703 m_pEdOutPos->GrabFocus();
704 m_pEdOutPos->SetSelection( Selection( 0, SELECTION_MAX ) );
706 else
708 m_pBtnCopyResult->Check( false );
709 m_pLbOutPos->Disable();
710 m_pEdOutPos->Disable();
711 m_pEdOutPos->SetText( EMPTY_OUSTRING );
715 bool ScTabPageSortOptions::FillItemSet( SfxItemSet* rArgSet )
717 // Create local copy of ScParam
718 ScSortParam aNewSortData = aSortData;
720 if (pDlg)
722 const SfxItemSet* pExample = pDlg->GetExampleSet();
723 const SfxPoolItem* pItem;
724 if ( pExample && pExample->GetItemState( nWhichSort, true, &pItem ) == SfxItemState::SET )
725 aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
727 aNewSortData.bByRow = m_pBtnTopDown->IsChecked();
728 aNewSortData.bHasHeader = m_pBtnHeader->IsChecked();
729 aNewSortData.bCaseSens = m_pBtnCase->IsChecked();
730 aNewSortData.bNaturalSort = m_pBtnNaturalSort->IsChecked();
731 aNewSortData.bIncludePattern = m_pBtnFormats->IsChecked();
732 aNewSortData.bInplace = !m_pBtnCopyResult->IsChecked();
733 aNewSortData.nDestCol = theOutPos.Col();
734 aNewSortData.nDestRow = theOutPos.Row();
735 aNewSortData.nDestTab = theOutPos.Tab();
736 aNewSortData.bUserDef = m_pBtnSortUser->IsChecked();
737 aNewSortData.nUserIndex = (m_pBtnSortUser->IsChecked())
738 ? m_pLbSortUser->GetSelectEntryPos()
739 : 0;
741 // get locale
742 LanguageType eLang = m_pLbLanguage->GetSelectLanguage();
743 aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);
745 // get algorithm
746 OUString sAlg;
747 if ( eLang != LANGUAGE_SYSTEM )
749 uno::Sequence<OUString> aAlgos = pColWrap->listCollatorAlgorithms(
750 aNewSortData.aCollatorLocale );
751 const sal_Int32 nSel = m_pLbAlgorithm->GetSelectEntryPos();
752 if ( nSel < aAlgos.getLength() )
753 sAlg = aAlgos[nSel];
755 aNewSortData.aCollatorAlgorithm = sAlg;
757 rArgSet->Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
759 return true;
762 // for data exchange without dialogue detour:
763 void ScTabPageSortOptions::ActivatePage( const SfxItemSet& rSet )
765 // Refresh local copy with shared data
766 aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
767 if ( pDlg )
769 if ( m_pBtnHeader->IsChecked() != pDlg->GetHeaders() )
771 m_pBtnHeader->Check( pDlg->GetHeaders() );
774 if ( m_pBtnTopDown->IsChecked() != pDlg->GetByRows() )
776 m_pBtnTopDown->Check( pDlg->GetByRows() );
777 m_pBtnLeftRight->Check( !pDlg->GetByRows() );
780 m_pBtnHeader->SetText( (pDlg->GetByRows())
781 ? aStrColLabel
782 : aStrRowLabel );
786 SfxTabPage::sfxpg ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )
788 bool bPosInputOk = true;
790 if ( m_pBtnCopyResult->IsChecked() )
792 OUString thePosStr = m_pEdOutPos->GetText();
793 ScAddress thePos;
794 sal_Int32 nColonPos = thePosStr.indexOf( ':' );
796 if ( -1 != nColonPos )
797 thePosStr = thePosStr.copy( 0, nColonPos );
799 if ( pViewData )
801 // visible table is default for input without table
802 // must be changed to GetRefTabNo when sorting has RefInput!
803 thePos.SetTab( pViewData->GetTabNo() );
806 ScRefFlags nResult = thePos.Parse( thePosStr, pDoc, pDoc->GetAddressConvention() );
808 bPosInputOk = (nResult & ScRefFlags::VALID) == ScRefFlags::VALID;
810 if ( !bPosInputOk )
812 ScopedVclPtrInstance<MessageDialog>(this, ScGlobal::GetRscString( STR_INVALID_TABREF))->Execute();
813 m_pEdOutPos->GrabFocus();
814 m_pEdOutPos->SetSelection( Selection( 0, SELECTION_MAX ) );
815 theOutPos.Set(0,0,0);
817 else
819 m_pEdOutPos->SetText( thePosStr );
820 theOutPos = thePos;
824 if ( pDlg && bPosInputOk )
826 pDlg->SetHeaders( m_pBtnHeader->IsChecked() );
827 pDlg->SetByRows ( m_pBtnTopDown->IsChecked() );
830 if ( pSetP && bPosInputOk )
831 FillItemSet( pSetP );
833 return bPosInputOk ? SfxTabPage::LEAVE_PAGE : SfxTabPage::KEEP_PAGE;
836 void ScTabPageSortOptions::FillUserSortListBox()
838 ScUserList* pUserLists = ScGlobal::GetUserList();
840 m_pLbSortUser->Clear();
841 if ( pUserLists )
843 size_t nCount = pUserLists->size();
844 if ( nCount > 0 )
845 for ( size_t i=0; i<nCount; ++i )
846 m_pLbSortUser->InsertEntry( (*pUserLists)[i].GetString() );
850 // Handler:
852 IMPL_LINK_TYPED( ScTabPageSortOptions, EnableHdl, Button*, pButton, void )
854 CheckBox* pBox = static_cast<CheckBox*>(pButton);
855 if (pBox == m_pBtnCopyResult)
857 if ( pBox->IsChecked() )
859 m_pLbOutPos->Enable();
860 m_pEdOutPos->Enable();
861 m_pEdOutPos->GrabFocus();
863 else
865 m_pLbOutPos->Disable();
866 m_pEdOutPos->Disable();
869 else if (pBox == m_pBtnSortUser)
871 if ( pBox->IsChecked() )
873 m_pLbSortUser->Enable();
874 m_pLbSortUser->GrabFocus();
876 else
877 m_pLbSortUser->Disable();
881 IMPL_LINK_TYPED( ScTabPageSortOptions, SelOutPosHdl, ListBox&, rLb, void )
883 if (&rLb == m_pLbOutPos)
885 OUString aString;
886 const sal_Int32 nSelPos = m_pLbOutPos->GetSelectEntryPos();
888 if ( nSelPos > 0 )
889 aString = *static_cast<OUString*>(m_pLbOutPos->GetEntryData( nSelPos ));
891 m_pEdOutPos->SetText( aString );
895 IMPL_LINK_TYPED( ScTabPageSortOptions, SortDirHdl, Button *, pBtn, void )
897 if (pBtn == m_pBtnTopDown)
899 m_pBtnHeader->SetText( aStrColLabel );
901 else if (pBtn == m_pBtnLeftRight)
903 m_pBtnHeader->SetText( aStrRowLabel );
907 void ScTabPageSortOptions::EdOutPosModHdl( Edit* pEd )
909 if (pEd == m_pEdOutPos)
911 OUString theCurPosStr = m_pEdOutPos->GetText();
912 ScRefFlags nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
914 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
916 bool bFound = false;
917 sal_Int32 i = 0;
918 const sal_Int32 nCount = m_pLbOutPos->GetEntryCount();
920 for ( i=2; i<nCount && !bFound; i++ )
922 OUString* pStr = static_cast<OUString*>(m_pLbOutPos->GetEntryData( i ));
923 bFound = (theCurPosStr == *pStr);
926 if ( bFound )
927 m_pLbOutPos->SelectEntryPos( --i );
928 else
929 m_pLbOutPos->SelectEntryPos( 0 );
934 IMPL_LINK_NOARG_TYPED(ScTabPageSortOptions, FillAlgorHdl, ListBox&, void)
936 m_pLbAlgorithm->SetUpdateMode( false );
937 m_pLbAlgorithm->Clear();
939 LanguageType eLang = m_pLbLanguage->GetSelectLanguage();
940 if ( eLang == LANGUAGE_SYSTEM )
942 // for LANGUAGE_SYSTEM no algorithm can be selected because
943 // it wouldn't necessarily exist for other languages
944 // -> leave list box empty if LANGUAGE_SYSTEM is selected
945 m_pFtAlgorithm->Enable( false ); // nothing to select
946 m_pLbAlgorithm->Enable( false ); // nothing to select
948 else
950 lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
951 uno::Sequence<OUString> aAlgos = pColWrap->listCollatorAlgorithms( aLocale );
953 long nCount = aAlgos.getLength();
954 const OUString* pArray = aAlgos.getConstArray();
955 for (long i=0; i<nCount; i++)
957 OUString sAlg = pArray[i];
958 OUString sUser = pColRes->GetTranslation( sAlg );
959 m_pLbAlgorithm->InsertEntry( sUser );
961 m_pLbAlgorithm->SelectEntryPos( 0 ); // first entry is default
962 m_pFtAlgorithm->Enable( nCount > 1 ); // enable only if there is a choice
963 m_pLbAlgorithm->Enable( nCount > 1 ); // enable only if there is a choice
966 m_pLbAlgorithm->SetUpdateMode( true );
969 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */