Line data Source code
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/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>
28 :
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"
41 :
42 : #include "sortkeydlg.hxx"
43 :
44 : #include "sortdlg.hxx"
45 :
46 : #include "tpsort.hxx"
47 :
48 : using namespace com::sun::star;
49 :
50 : /*
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.
54 : *
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()).
58 : *
59 : * In the meantime the class SfxTabPage offers the following method:
60 : *
61 : * virtual sal_Bool HasExchangeSupport() const; -> return sal_True;
62 : * virtual void ActivatePage(const SfxItemSet &);
63 : * virtual int DeactivatePage(SfxItemSet * = 0);
64 : *
65 : * This still needs to be changed!
66 : */
67 :
68 : // Sort Criteria Tab page
69 :
70 0 : ScTabPageSortFields::ScTabPageSortFields(vcl::Window* pParent,
71 : const SfxItemSet& rArgSet)
72 : : SfxTabPage(pParent, "SortCriteriaPage",
73 : "modules/scalc/ui/sortcriteriapage.ui", &rArgSet)
74 : ,
75 :
76 : aStrUndefined ( SC_RESSTR( SCSTR_UNDEFINED ) ),
77 : aStrColumn ( SC_RESSTR( SCSTR_COLUMN ) ),
78 : aStrRow ( SC_RESSTR( SCSTR_ROW ) ),
79 :
80 0 : nWhichSort ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
81 0 : pDlg ( static_cast<ScSortDlg*>(GetParentDialog()) ),
82 : pViewData ( NULL ),
83 : aSortData ( static_cast<const ScSortItem&>(
84 0 : rArgSet.Get( nWhichSort )).
85 0 : GetSortData() ),
86 : nFieldCount ( 0 ),
87 : nSortKeyCount ( DEFSORT ),
88 : bHasHeader ( false ),
89 : bSortByRows ( false ),
90 0 : maSortKeyCtrl ( this, maSortKeyItems )
91 : {
92 0 : Init();
93 0 : SetExchangeSupport();
94 0 : }
95 :
96 0 : ScTabPageSortFields::~ScTabPageSortFields()
97 : {
98 0 : disposeOnce();
99 0 : }
100 :
101 0 : void ScTabPageSortFields::dispose()
102 : {
103 0 : pDlg.clear();
104 0 : maSortKeyItems.clear();
105 0 : maSortKeyCtrl.dispose();
106 0 : SfxTabPage::dispose();
107 0 : }
108 :
109 0 : void ScTabPageSortFields::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
110 : {
111 0 : SfxTabPage::SetPosSizePixel(rAllocPos, rAllocation);
112 0 : maSortKeyCtrl.setScrollRange();
113 0 : }
114 :
115 0 : void ScTabPageSortFields::SetSizePixel(const Size& rAllocation)
116 : {
117 0 : SfxTabPage::SetSizePixel(rAllocation);
118 0 : maSortKeyCtrl.setScrollRange();
119 0 : }
120 :
121 0 : void ScTabPageSortFields::SetPosPixel(const Point& rAllocPos)
122 : {
123 0 : SfxTabPage::SetPosPixel(rAllocPos);
124 0 : maSortKeyCtrl.setScrollRange();
125 0 : }
126 :
127 0 : void ScTabPageSortFields::Init()
128 : {
129 : const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
130 0 : GetItemSet().Get( nWhichSort ));
131 :
132 0 : pViewData = rSortItem.GetViewData();
133 : OSL_ENSURE( pViewData, "ViewData not found!" );
134 :
135 0 : nFieldArr.push_back( 0 );
136 0 : nFirstCol = 0;
137 0 : nFirstRow = 0;
138 :
139 : // Create three sort key dialogs by default
140 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
141 : {
142 0 : maSortKeyCtrl.AddSortKey(i+1);
143 0 : maSortKeyItems[i].m_pLbSort->SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
144 : }
145 0 : }
146 :
147 0 : VclPtr<SfxTabPage> ScTabPageSortFields::Create( vcl::Window* pParent,
148 : const SfxItemSet* rArgSet )
149 : {
150 0 : return VclPtr<ScTabPageSortFields>::Create( pParent, *rArgSet );
151 : }
152 :
153 0 : void ScTabPageSortFields::Reset( const SfxItemSet* /* rArgSet */ )
154 : {
155 0 : bSortByRows = aSortData.bByRow;
156 0 : bHasHeader = aSortData.bHasHeader;
157 :
158 0 : if ( maSortKeyItems[0].m_pLbSort->GetEntryCount() == 0 )
159 0 : FillFieldLists(0);
160 :
161 : // ListBox selection:
162 0 : if (!aSortData.maKeyState.empty() && aSortData.maKeyState[0].bDoSort)
163 : {
164 : // Make sure that the all sort keys are reset
165 0 : for ( sal_uInt16 i=nSortKeyCount; i<aSortData.GetSortKeyCount(); i++ )
166 : {
167 0 : maSortKeyCtrl.AddSortKey(i+1);
168 0 : maSortKeyItems[i].m_pLbSort->SetSelectHdl( LINK( this,
169 0 : ScTabPageSortFields, SelectHdl ) );
170 : }
171 0 : nSortKeyCount = aSortData.GetSortKeyCount();
172 0 : FillFieldLists(0);
173 :
174 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
175 : {
176 0 : if (aSortData.maKeyState[i].bDoSort )
177 : {
178 0 : maSortKeyItems[i].m_pLbSort->SelectEntryPos( GetFieldSelPos(
179 0 : aSortData.maKeyState[i].nField ) );
180 0 : (aSortData.maKeyState[i].bAscending)
181 0 : ? maSortKeyItems[i].m_pBtnUp->Check()
182 0 : : maSortKeyItems[i].m_pBtnDown->Check();
183 : }
184 : else
185 : {
186 0 : maSortKeyItems[i].m_pLbSort->SelectEntryPos( 0 ); // Select none
187 0 : maSortKeyItems[i].m_pBtnUp->Check();
188 : }
189 : }
190 :
191 : // Enable or disable field depending on preceding Listbox selection
192 0 : maSortKeyItems[0].EnableField();
193 0 : for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
194 0 : if ( maSortKeyItems[i - 1].m_pLbSort->GetSelectEntryPos() == 0 )
195 0 : maSortKeyItems[i].DisableField();
196 : else
197 0 : maSortKeyItems[i].EnableField();
198 : }
199 : else
200 : {
201 0 : SCCOL nCol = pViewData->GetCurX();
202 :
203 0 : if( nCol < aSortData.nCol1 )
204 0 : nCol = aSortData.nCol1;
205 0 : else if( nCol > aSortData.nCol2 )
206 0 : nCol = aSortData.nCol2;
207 :
208 0 : sal_uInt16 nSort1Pos = nCol - aSortData.nCol1+1;
209 :
210 0 : maSortKeyItems[0].m_pLbSort->SelectEntryPos( nSort1Pos );
211 0 : for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
212 0 : maSortKeyItems[i].m_pLbSort->SelectEntryPos( 0 );
213 :
214 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
215 0 : maSortKeyItems[i].m_pBtnUp->Check();
216 :
217 0 : maSortKeyItems[0].EnableField();
218 0 : maSortKeyItems[1].EnableField();
219 0 : for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
220 0 : maSortKeyItems[i].DisableField();
221 : }
222 :
223 0 : if ( pDlg )
224 : {
225 0 : pDlg->SetByRows ( bSortByRows );
226 0 : pDlg->SetHeaders( bHasHeader );
227 : }
228 :
229 : // Make sure that there is always a last undefined sort key
230 0 : if ( maSortKeyItems[nSortKeyCount - 1].m_pLbSort->GetSelectEntryPos() > 0 )
231 0 : SetLastSortKey( nSortKeyCount );
232 0 : }
233 :
234 0 : bool ScTabPageSortFields::FillItemSet( SfxItemSet* rArgSet )
235 : {
236 0 : ScSortParam aNewSortData = aSortData;
237 :
238 0 : if (pDlg)
239 : {
240 0 : const SfxItemSet* pExample = pDlg->GetExampleSet();
241 : const SfxPoolItem* pItem;
242 0 : if ( pExample && pExample->GetItemState( nWhichSort, true, &pItem ) == SfxItemState::SET )
243 : {
244 0 : ScSortParam aTempData = static_cast<const ScSortItem*>(pItem)->GetSortData();
245 0 : aTempData.maKeyState = aNewSortData.maKeyState;
246 0 : aNewSortData = aTempData;
247 : }
248 : }
249 0 : std::vector<sal_Int32> nSortPos;
250 :
251 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
252 : {
253 0 : nSortPos.push_back( maSortKeyItems[i].m_pLbSort->GetSelectEntryPos() );
254 :
255 0 : if ( nSortPos[i] == LISTBOX_ENTRY_NOTFOUND ) nSortPos[i] = 0;
256 : }
257 :
258 0 : if( nSortKeyCount >= aNewSortData.GetSortKeyCount() )
259 0 : aNewSortData.maKeyState.resize(nSortKeyCount);
260 :
261 0 : if ( nSortPos[0] > 0 )
262 : {
263 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
264 0 : aNewSortData.maKeyState[i].bDoSort = (nSortPos[i] > 0);
265 :
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 0 : if ( pDlg && bSortByRows != pDlg->GetByRows() )
270 : {
271 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
272 0 : aNewSortData.maKeyState[i].nField = ( bSortByRows ?
273 : static_cast<SCCOLROW>(nFirstRow) :
274 0 : static_cast<SCCOLROW>(nFirstCol) );
275 : }
276 : else
277 : {
278 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
279 0 : aNewSortData.maKeyState[i].nField = nFieldArr[nSortPos[i]];
280 : }
281 :
282 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
283 0 : aNewSortData.maKeyState[i].bAscending = maSortKeyItems[i].m_pBtnUp->IsChecked();
284 :
285 : // bHasHeader is in ScTabPageSortOptions::FillItemSet, where it belongs
286 : }
287 : else
288 : {
289 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
290 0 : aNewSortData.maKeyState[i].bDoSort = false;
291 : }
292 :
293 0 : rArgSet->Put( ScSortItem( SCITEM_SORTDATA, NULL, &aNewSortData ) );
294 :
295 0 : return true;
296 : }
297 :
298 : // for data exchange without dialogue detour:
299 0 : void ScTabPageSortFields::ActivatePage( const SfxItemSet& rSet )
300 : {
301 : // Refresh local copy with shared data
302 0 : aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
303 0 : if ( pDlg )
304 : {
305 0 : if ( bHasHeader != pDlg->GetHeaders()
306 0 : || bSortByRows != pDlg->GetByRows() )
307 : {
308 0 : std::vector<sal_uInt16> nCurSel;
309 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
310 0 : nCurSel.push_back( maSortKeyItems[i].m_pLbSort->GetSelectEntryPos() );
311 :
312 0 : bHasHeader = pDlg->GetHeaders();
313 0 : bSortByRows = pDlg->GetByRows();
314 0 : FillFieldLists(0);
315 :
316 0 : for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
317 0 : maSortKeyItems[i].m_pLbSort->SelectEntryPos( nCurSel[i] );
318 : }
319 : }
320 0 : }
321 :
322 0 : SfxTabPage::sfxpg ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
323 : {
324 0 : if ( pDlg )
325 : {
326 0 : if ( bHasHeader != pDlg->GetHeaders() )
327 0 : pDlg->SetHeaders( bHasHeader );
328 :
329 0 : if ( bSortByRows != pDlg->GetByRows() )
330 0 : pDlg->SetByRows( bSortByRows );
331 : }
332 :
333 0 : if ( pSetP )
334 0 : FillItemSet( pSetP );
335 :
336 0 : return SfxTabPage::LEAVE_PAGE;
337 : }
338 :
339 0 : void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
340 : {
341 0 : if ( pViewData )
342 : {
343 0 : ScDocument* pDoc = pViewData->GetDocument();
344 :
345 0 : if ( pDoc )
346 : {
347 0 : for ( sal_uInt16 i=nStartField; i<nSortKeyCount; i++ )
348 : {
349 0 : maSortKeyItems[i].m_pLbSort->Clear();
350 0 : maSortKeyItems[i].m_pLbSort->InsertEntry( aStrUndefined, 0 );
351 : }
352 :
353 0 : SCCOL nFirstSortCol = aSortData.nCol1;
354 0 : SCROW nFirstSortRow = aSortData.nRow1;
355 0 : SCTAB nTab = pViewData->GetTabNo();
356 0 : sal_uInt16 i = 1;
357 0 : nFieldArr.clear();
358 0 : nFieldArr.push_back(0);
359 :
360 0 : if ( bSortByRows )
361 : {
362 0 : OUString aFieldName;
363 0 : SCCOL nMaxCol = aSortData.nCol2;
364 : SCCOL col;
365 :
366 0 : for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
367 : {
368 0 : aFieldName = pDoc->GetString(col, nFirstSortRow, nTab);
369 0 : if ( !bHasHeader || aFieldName.isEmpty() )
370 : {
371 0 : aFieldName = ScGlobal::ReplaceOrAppend( aStrColumn, "%1", ScColToAlpha( col ));
372 : }
373 0 : nFieldArr.push_back( col );
374 :
375 0 : for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
376 0 : maSortKeyItems[j].m_pLbSort->InsertEntry( aFieldName, i );
377 :
378 0 : i++;
379 0 : }
380 : }
381 : else
382 : {
383 0 : OUString aFieldName;
384 0 : SCROW nMaxRow = aSortData.nRow2;
385 : SCROW row;
386 :
387 0 : for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS; row++ )
388 : {
389 0 : aFieldName = pDoc->GetString(nFirstSortCol, row, nTab);
390 0 : if ( !bHasHeader || aFieldName.isEmpty() )
391 : {
392 0 : aFieldName = ScGlobal::ReplaceOrAppend( aStrRow, "%1", OUString::number( row+1));
393 : }
394 0 : nFieldArr.push_back( row );
395 :
396 0 : for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
397 0 : maSortKeyItems[j].m_pLbSort->InsertEntry( aFieldName, i );
398 :
399 0 : i++;
400 0 : }
401 : }
402 0 : nFieldCount = i;
403 : }
404 : }
405 0 : }
406 :
407 0 : sal_uInt16 ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
408 : {
409 0 : sal_uInt16 nFieldPos = 0;
410 0 : bool bFound = false;
411 :
412 0 : for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
413 : {
414 0 : if ( nFieldArr[n] == nField )
415 : {
416 0 : nFieldPos = n;
417 0 : bFound = true;
418 : }
419 : }
420 :
421 0 : return nFieldPos;
422 : }
423 :
424 0 : void ScTabPageSortFields::SetLastSortKey( sal_uInt16 nItem )
425 : {
426 : // Extend local SortParam copy
427 0 : const ScSortKeyState atempKeyState = { false, 0, true };
428 0 : aSortData.maKeyState.push_back( atempKeyState );
429 :
430 : // Add Sort Key Item
431 0 : ++nSortKeyCount;
432 0 : maSortKeyCtrl.AddSortKey( nSortKeyCount );
433 0 : maSortKeyItems[nItem].m_pLbSort->SetSelectHdl(
434 0 : LINK( this, ScTabPageSortFields, SelectHdl ) );
435 :
436 0 : FillFieldLists( nItem );
437 :
438 : // Set Status
439 0 : maSortKeyItems[nItem].m_pBtnUp->Check();
440 0 : maSortKeyItems[nItem].m_pLbSort->SelectEntryPos( 0 );
441 0 : }
442 :
443 : // Handler:
444 :
445 0 : IMPL_LINK( ScTabPageSortFields, SelectHdl, ListBox *, pLb )
446 : {
447 0 : OUString aSelEntry = pLb->GetSelectEntry();
448 0 : ScSortKeyItems::iterator pIter;
449 :
450 : // If last listbox is enabled add one item
451 0 : if ( maSortKeyItems.back().m_pLbSort == pLb )
452 0 : if ( aSelEntry != aStrUndefined )
453 : {
454 0 : SetLastSortKey( nSortKeyCount );
455 0 : return 0;
456 : }
457 :
458 : // Find selected listbox
459 0 : for ( pIter = maSortKeyItems.begin(); pIter != maSortKeyItems.end(); ++pIter )
460 : {
461 0 : if ( pIter->m_pLbSort == pLb ) break;
462 : }
463 :
464 : // If not selecting the last Listbox, modify the succeeding ones
465 0 : ++pIter;
466 0 : if ( std::distance(maSortKeyItems.begin(), pIter) < nSortKeyCount )
467 : {
468 0 : if ( aSelEntry == aStrUndefined )
469 : {
470 0 : for ( ; pIter != maSortKeyItems.end(); ++pIter )
471 : {
472 0 : pIter->m_pLbSort->SelectEntryPos( 0 );
473 :
474 0 : if ( pIter->m_pFlSort->IsEnabled() )
475 0 : pIter->DisableField();
476 : }
477 : }
478 : else
479 : {
480 0 : if ( !pIter->m_pFlSort->IsEnabled() )
481 0 : pIter->EnableField();
482 : }
483 : }
484 0 : return 0;
485 : }
486 :
487 : // Sort option Tab Page:
488 :
489 0 : ScTabPageSortOptions::ScTabPageSortOptions( vcl::Window* pParent,
490 : const SfxItemSet& rArgSet )
491 : : SfxTabPage(pParent, "SortOptionsPage",
492 : "modules/scalc/ui/sortoptionspage.ui", &rArgSet)
493 : , aStrRowLabel(SC_RESSTR(SCSTR_ROW_LABEL))
494 : , aStrColLabel(SC_RESSTR(SCSTR_COL_LABEL))
495 : , aStrUndefined(SC_RESSTR(SCSTR_UNDEFINED))
496 0 : , nWhichSort(rArgSet.GetPool()->GetWhich(SID_SORT))
497 0 : , aSortData(static_cast<const ScSortItem&>(rArgSet.Get(nWhichSort)).GetSortData())
498 : , pViewData(NULL)
499 : , pDoc(NULL)
500 0 : , pDlg(static_cast<ScSortDlg*>(GetParentDialog()))
501 : , pColRes( NULL )
502 0 : , pColWrap( NULL )
503 : {
504 0 : get(m_pBtnCase, "case");
505 0 : get(m_pBtnHeader, "header");
506 0 : get(m_pBtnFormats, "formats");
507 0 : get(m_pBtnNaturalSort, "naturalsort");
508 0 : get(m_pBtnCopyResult, "copyresult");
509 0 : get(m_pLbOutPos, "outarealb");
510 0 : get(m_pEdOutPos, "outareaed");
511 0 : get(m_pBtnSortUser, "sortuser");
512 0 : get(m_pLbSortUser, "sortuserlb");
513 0 : get(m_pFtAlgorithm, "algorithmft");
514 0 : get(m_pLbAlgorithm, "algorithmlb");
515 0 : get(m_pBtnTopDown, "topdown");
516 0 : get(m_pBtnLeftRight, "leftright");
517 0 : get(m_pLbLanguage, "language");
518 0 : Init();
519 0 : SetExchangeSupport();
520 :
521 0 : m_pLbOutPos->SetAccessibleName(m_pBtnCopyResult->GetText());
522 0 : m_pEdOutPos->SetAccessibleName(m_pBtnCopyResult->GetText());
523 0 : m_pLbSortUser->SetAccessibleName(m_pBtnSortUser->GetText());
524 0 : }
525 :
526 0 : ScTabPageSortOptions::~ScTabPageSortOptions()
527 : {
528 0 : disposeOnce();
529 0 : }
530 :
531 0 : void ScTabPageSortOptions::dispose()
532 : {
533 0 : sal_uInt16 nEntries = m_pLbOutPos->GetEntryCount();
534 :
535 0 : for ( sal_uInt16 i=1; i<nEntries; i++ )
536 0 : delete static_cast<OUString*>(m_pLbOutPos->GetEntryData( i ));
537 :
538 0 : delete pColRes;
539 0 : delete pColWrap; //! not if from document
540 0 : m_pBtnCase.clear();
541 0 : m_pBtnHeader.clear();
542 0 : m_pBtnFormats.clear();
543 0 : m_pBtnNaturalSort.clear();
544 0 : m_pBtnCopyResult.clear();
545 0 : m_pLbOutPos.clear();
546 0 : m_pEdOutPos.clear();
547 0 : m_pBtnSortUser.clear();
548 0 : m_pLbSortUser.clear();
549 0 : m_pLbLanguage.clear();
550 0 : m_pFtAlgorithm.clear();
551 0 : m_pLbAlgorithm.clear();
552 0 : m_pBtnTopDown.clear();
553 0 : m_pBtnLeftRight.clear();
554 0 : pDlg.clear();
555 0 : SfxTabPage::dispose();
556 0 : }
557 :
558 0 : void ScTabPageSortOptions::Init()
559 : {
560 : // CollatorResource has user-visible names for sort algorithms
561 0 : pColRes = new CollatorResource();
562 :
563 : //! use CollatorWrapper from document?
564 0 : pColWrap = new CollatorWrapper( comphelper::getProcessComponentContext() );
565 :
566 : const ScSortItem& rSortItem = static_cast<const ScSortItem&>(
567 0 : GetItemSet().Get( nWhichSort ));
568 :
569 0 : m_pLbOutPos->SetSelectHdl ( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
570 0 : m_pBtnCopyResult->SetClickHdl( LINK( this, ScTabPageSortOptions, EnableHdl ) );
571 0 : m_pBtnSortUser->SetClickHdl ( LINK( this, ScTabPageSortOptions, EnableHdl ) );
572 0 : m_pBtnTopDown->SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
573 0 : m_pBtnLeftRight->SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
574 0 : m_pLbLanguage->SetSelectHdl ( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
575 :
576 0 : pViewData = rSortItem.GetViewData();
577 0 : pDoc = pViewData ? pViewData->GetDocument() : NULL;
578 :
579 : OSL_ENSURE( pViewData, "ViewData not found! :-/" );
580 :
581 0 : if ( pViewData && pDoc )
582 : {
583 0 : ScDBCollection* pDBColl = pDoc->GetDBCollection();
584 0 : const SCTAB nCurTab = pViewData->GetTabNo();
585 0 : OUString theDbName = OUString(STR_DB_LOCAL_NONAME);
586 0 : const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
587 :
588 0 : m_pLbOutPos->Clear();
589 0 : m_pLbOutPos->InsertEntry( aStrUndefined, 0 );
590 0 : m_pLbOutPos->Disable();
591 :
592 0 : ScAreaNameIterator aIter( pDoc );
593 0 : OUString aName;
594 0 : ScRange aRange;
595 0 : while ( aIter.Next( aName, aRange ) )
596 : {
597 0 : sal_uInt16 nInsert = m_pLbOutPos->InsertEntry( aName );
598 :
599 0 : OUString aRefStr(aRange.aStart.Format(SCA_ABS_3D, pDoc, eConv));
600 0 : m_pLbOutPos->SetEntryData( nInsert, new OUString( aRefStr ) );
601 0 : }
602 :
603 0 : m_pLbOutPos->SelectEntryPos( 0 );
604 0 : m_pEdOutPos->SetText( EMPTY_OUSTRING );
605 :
606 : // Check whether the field that is passed on is a database field:
607 :
608 0 : ScAddress aScAddress( aSortData.nCol1, aSortData.nRow1, nCurTab );
609 : OUString theArea =
610 : ScRange( aScAddress,
611 : ScAddress( aSortData.nCol2, aSortData.nRow2, nCurTab )
612 0 : ).Format(SCR_ABS, pDoc, eConv);
613 :
614 0 : if ( pDBColl )
615 : {
616 : ScDBData* pDBData
617 : = pDBColl->GetDBAtArea( nCurTab,
618 : aSortData.nCol1, aSortData.nRow1,
619 0 : aSortData.nCol2, aSortData.nRow2 );
620 0 : if ( pDBData )
621 : {
622 0 : theDbName = pDBData->GetName();
623 0 : m_pBtnHeader->Check( pDBData->HasHeader() );
624 : }
625 : }
626 :
627 0 : theArea += " (" + theDbName + ")";
628 :
629 0 : m_pBtnHeader->SetText( aStrColLabel );
630 : }
631 :
632 0 : FillUserSortListBox();
633 :
634 : // get available languages
635 :
636 0 : m_pLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false );
637 0 : m_pLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
638 0 : }
639 :
640 0 : VclPtr<SfxTabPage> ScTabPageSortOptions::Create( vcl::Window* pParent,
641 : const SfxItemSet* rArgSet )
642 : {
643 0 : return VclPtr<ScTabPageSortOptions>::Create( pParent, *rArgSet );
644 : }
645 :
646 0 : void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
647 : {
648 0 : if ( aSortData.bUserDef )
649 : {
650 0 : m_pBtnSortUser->Check( true );
651 0 : m_pLbSortUser->Enable();
652 0 : m_pLbSortUser->SelectEntryPos( aSortData.nUserIndex );
653 : }
654 : else
655 : {
656 0 : m_pBtnSortUser->Check( false );
657 0 : m_pLbSortUser->Disable();
658 0 : m_pLbSortUser->SelectEntryPos( 0 );
659 : }
660 :
661 0 : m_pBtnCase->Check ( aSortData.bCaseSens );
662 0 : m_pBtnFormats->Check ( aSortData.bIncludePattern );
663 0 : m_pBtnHeader->Check ( aSortData.bHasHeader );
664 0 : m_pBtnNaturalSort->Check ( aSortData.bNaturalSort );
665 :
666 0 : if ( aSortData.bByRow )
667 : {
668 0 : m_pBtnTopDown->Check();
669 0 : m_pBtnHeader->SetText( aStrColLabel );
670 : }
671 : else
672 : {
673 0 : m_pBtnLeftRight->Check();
674 0 : m_pBtnHeader->SetText( aStrRowLabel );
675 : }
676 :
677 0 : LanguageType eLang = LanguageTag::convertToLanguageType( aSortData.aCollatorLocale, false);
678 0 : if ( eLang == LANGUAGE_DONTKNOW )
679 0 : eLang = LANGUAGE_SYSTEM;
680 0 : m_pLbLanguage->SelectLanguage( eLang );
681 0 : FillAlgorHdl(m_pLbLanguage); // get algorithms, select default
682 0 : if ( !aSortData.aCollatorAlgorithm.isEmpty() )
683 0 : m_pLbAlgorithm->SelectEntry( pColRes->GetTranslation( aSortData.aCollatorAlgorithm ) );
684 :
685 0 : if ( pDoc && !aSortData.bInplace )
686 : {
687 0 : sal_uInt16 nFormat = (aSortData.nDestTab != pViewData->GetTabNo())
688 : ? SCR_ABS_3D
689 0 : : SCR_ABS;
690 :
691 : theOutPos.Set( aSortData.nDestCol,
692 : aSortData.nDestRow,
693 0 : aSortData.nDestTab );
694 :
695 0 : OUString aStr(theOutPos.Format(nFormat, pDoc, pDoc->GetAddressConvention()));
696 0 : m_pBtnCopyResult->Check();
697 0 : m_pLbOutPos->Enable();
698 0 : m_pEdOutPos->Enable();
699 0 : m_pEdOutPos->SetText( aStr );
700 0 : EdOutPosModHdl(m_pEdOutPos);
701 0 : m_pEdOutPos->GrabFocus();
702 0 : m_pEdOutPos->SetSelection( Selection( 0, SELECTION_MAX ) );
703 : }
704 : else
705 : {
706 0 : m_pBtnCopyResult->Check( false );
707 0 : m_pLbOutPos->Disable();
708 0 : m_pEdOutPos->Disable();
709 0 : m_pEdOutPos->SetText( EMPTY_OUSTRING );
710 : }
711 0 : }
712 :
713 0 : bool ScTabPageSortOptions::FillItemSet( SfxItemSet* rArgSet )
714 : {
715 : // Create local copy of ScParam
716 0 : ScSortParam aNewSortData = aSortData;
717 :
718 0 : if (pDlg)
719 : {
720 0 : const SfxItemSet* pExample = pDlg->GetExampleSet();
721 : const SfxPoolItem* pItem;
722 0 : if ( pExample && pExample->GetItemState( nWhichSort, true, &pItem ) == SfxItemState::SET )
723 0 : aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
724 : }
725 0 : aNewSortData.bByRow = m_pBtnTopDown->IsChecked();
726 0 : aNewSortData.bHasHeader = m_pBtnHeader->IsChecked();
727 0 : aNewSortData.bCaseSens = m_pBtnCase->IsChecked();
728 0 : aNewSortData.bNaturalSort = m_pBtnNaturalSort->IsChecked();
729 0 : aNewSortData.bIncludePattern = m_pBtnFormats->IsChecked();
730 0 : aNewSortData.bInplace = !m_pBtnCopyResult->IsChecked();
731 0 : aNewSortData.nDestCol = theOutPos.Col();
732 0 : aNewSortData.nDestRow = theOutPos.Row();
733 0 : aNewSortData.nDestTab = theOutPos.Tab();
734 0 : aNewSortData.bUserDef = m_pBtnSortUser->IsChecked();
735 0 : aNewSortData.nUserIndex = (m_pBtnSortUser->IsChecked())
736 0 : ? m_pLbSortUser->GetSelectEntryPos()
737 0 : : 0;
738 :
739 : // get locale
740 0 : LanguageType eLang = m_pLbLanguage->GetSelectLanguage();
741 0 : aNewSortData.aCollatorLocale = LanguageTag::convertToLocale( eLang, false);
742 :
743 : // get algorithm
744 0 : OUString sAlg;
745 0 : if ( eLang != LANGUAGE_SYSTEM )
746 : {
747 : uno::Sequence<OUString> aAlgos = pColWrap->listCollatorAlgorithms(
748 0 : aNewSortData.aCollatorLocale );
749 0 : sal_uInt16 nSel = m_pLbAlgorithm->GetSelectEntryPos();
750 0 : if ( nSel < aAlgos.getLength() )
751 0 : sAlg = aAlgos[nSel];
752 : }
753 0 : aNewSortData.aCollatorAlgorithm = sAlg;
754 :
755 0 : rArgSet->Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
756 :
757 0 : return true;
758 : }
759 :
760 : // for data exchange without dialogue detour:
761 0 : void ScTabPageSortOptions::ActivatePage( const SfxItemSet& rSet )
762 : {
763 : // Refresh local copy with shared data
764 0 : aSortData = static_cast<const ScSortItem&>(rSet.Get( SCITEM_SORTDATA )).GetSortData();
765 0 : if ( pDlg )
766 : {
767 0 : if ( m_pBtnHeader->IsChecked() != pDlg->GetHeaders() )
768 : {
769 0 : m_pBtnHeader->Check( pDlg->GetHeaders() );
770 : }
771 :
772 0 : if ( m_pBtnTopDown->IsChecked() != pDlg->GetByRows() )
773 : {
774 0 : m_pBtnTopDown->Check( pDlg->GetByRows() );
775 0 : m_pBtnLeftRight->Check( !pDlg->GetByRows() );
776 : }
777 :
778 0 : m_pBtnHeader->SetText( (pDlg->GetByRows())
779 : ? aStrColLabel
780 0 : : aStrRowLabel );
781 : }
782 0 : }
783 :
784 0 : SfxTabPage::sfxpg ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )
785 : {
786 0 : bool bPosInputOk = true;
787 :
788 0 : if ( m_pBtnCopyResult->IsChecked() )
789 : {
790 0 : OUString thePosStr = m_pEdOutPos->GetText();
791 0 : ScAddress thePos;
792 0 : sal_Int32 nColonPos = thePosStr.indexOf( ':' );
793 :
794 0 : if ( -1 != nColonPos )
795 0 : thePosStr = thePosStr.copy( 0, nColonPos );
796 :
797 0 : if ( pViewData )
798 : {
799 : // visible table is default for input without table
800 : // must be changed to GetRefTabNo when sorting has RefInput!
801 0 : thePos.SetTab( pViewData->GetTabNo() );
802 : }
803 :
804 0 : sal_uInt16 nResult = thePos.Parse( thePosStr, pDoc, pDoc->GetAddressConvention() );
805 :
806 0 : bPosInputOk = ( SCA_VALID == (nResult & SCA_VALID) );
807 :
808 0 : if ( !bPosInputOk )
809 : {
810 0 : ScopedVclPtrInstance<MessageDialog>::Create(this, ScGlobal::GetRscString( STR_INVALID_TABREF))->Execute();
811 0 : m_pEdOutPos->GrabFocus();
812 0 : m_pEdOutPos->SetSelection( Selection( 0, SELECTION_MAX ) );
813 0 : theOutPos.Set(0,0,0);
814 : }
815 : else
816 : {
817 0 : m_pEdOutPos->SetText( thePosStr );
818 0 : theOutPos = thePos;
819 0 : }
820 : }
821 :
822 0 : if ( pDlg && bPosInputOk )
823 : {
824 0 : pDlg->SetHeaders( m_pBtnHeader->IsChecked() );
825 0 : pDlg->SetByRows ( m_pBtnTopDown->IsChecked() );
826 : }
827 :
828 0 : if ( pSetP && bPosInputOk )
829 0 : FillItemSet( pSetP );
830 :
831 0 : return bPosInputOk ? SfxTabPage::LEAVE_PAGE : SfxTabPage::KEEP_PAGE;
832 : }
833 :
834 0 : void ScTabPageSortOptions::FillUserSortListBox()
835 : {
836 0 : ScUserList* pUserLists = ScGlobal::GetUserList();
837 :
838 0 : m_pLbSortUser->Clear();
839 0 : if ( pUserLists )
840 : {
841 0 : size_t nCount = pUserLists->size();
842 0 : if ( nCount > 0 )
843 0 : for ( size_t i=0; i<nCount; ++i )
844 0 : m_pLbSortUser->InsertEntry( (*pUserLists)[i]->GetString() );
845 : }
846 0 : }
847 :
848 : // Handler:
849 :
850 0 : IMPL_LINK( ScTabPageSortOptions, EnableHdl, CheckBox *, pBox )
851 : {
852 0 : if (pBox == m_pBtnCopyResult)
853 : {
854 0 : if ( pBox->IsChecked() )
855 : {
856 0 : m_pLbOutPos->Enable();
857 0 : m_pEdOutPos->Enable();
858 0 : m_pEdOutPos->GrabFocus();
859 : }
860 : else
861 : {
862 0 : m_pLbOutPos->Disable();
863 0 : m_pEdOutPos->Disable();
864 : }
865 : }
866 0 : else if (pBox == m_pBtnSortUser)
867 : {
868 0 : if ( pBox->IsChecked() )
869 : {
870 0 : m_pLbSortUser->Enable();
871 0 : m_pLbSortUser->GrabFocus();
872 : }
873 : else
874 0 : m_pLbSortUser->Disable();
875 : }
876 0 : return 0;
877 : }
878 :
879 0 : IMPL_LINK( ScTabPageSortOptions, SelOutPosHdl, ListBox *, pLb )
880 : {
881 0 : if (pLb == m_pLbOutPos)
882 : {
883 0 : OUString aString;
884 0 : sal_uInt16 nSelPos = m_pLbOutPos->GetSelectEntryPos();
885 :
886 0 : if ( nSelPos > 0 )
887 0 : aString = *static_cast<OUString*>(m_pLbOutPos->GetEntryData( nSelPos ));
888 :
889 0 : m_pEdOutPos->SetText( aString );
890 : }
891 0 : return 0;
892 : }
893 :
894 0 : IMPL_LINK( ScTabPageSortOptions, SortDirHdl, RadioButton *, pBtn )
895 : {
896 0 : if (pBtn == m_pBtnTopDown)
897 : {
898 0 : m_pBtnHeader->SetText( aStrColLabel );
899 : }
900 0 : else if (pBtn == m_pBtnLeftRight)
901 : {
902 0 : m_pBtnHeader->SetText( aStrRowLabel );
903 : }
904 0 : return 0;
905 : }
906 :
907 0 : void ScTabPageSortOptions::EdOutPosModHdl( Edit* pEd )
908 : {
909 0 : if (pEd == m_pEdOutPos)
910 : {
911 0 : OUString theCurPosStr = m_pEdOutPos->GetText();
912 0 : sal_uInt16 nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
913 :
914 0 : if ( SCA_VALID == (nResult & SCA_VALID) )
915 : {
916 0 : bool bFound = false;
917 0 : sal_uInt16 i = 0;
918 0 : sal_uInt16 nCount = m_pLbOutPos->GetEntryCount();
919 :
920 0 : for ( i=2; i<nCount && !bFound; i++ )
921 : {
922 0 : OUString* pStr = static_cast<OUString*>(m_pLbOutPos->GetEntryData( i ));
923 0 : bFound = (theCurPosStr == *pStr);
924 : }
925 :
926 0 : if ( bFound )
927 0 : m_pLbOutPos->SelectEntryPos( --i );
928 : else
929 0 : m_pLbOutPos->SelectEntryPos( 0 );
930 0 : }
931 : }
932 0 : }
933 :
934 0 : IMPL_LINK_NOARG(ScTabPageSortOptions, FillAlgorHdl)
935 : {
936 0 : m_pLbAlgorithm->SetUpdateMode( false );
937 0 : m_pLbAlgorithm->Clear();
938 :
939 0 : LanguageType eLang = m_pLbLanguage->GetSelectLanguage();
940 0 : if ( eLang == LANGUAGE_SYSTEM )
941 : {
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 0 : m_pFtAlgorithm->Enable( false ); // nothing to select
946 0 : m_pLbAlgorithm->Enable( false ); // nothing to select
947 : }
948 : else
949 : {
950 0 : lang::Locale aLocale( LanguageTag::convertToLocale( eLang ));
951 0 : uno::Sequence<OUString> aAlgos = pColWrap->listCollatorAlgorithms( aLocale );
952 :
953 0 : long nCount = aAlgos.getLength();
954 0 : const OUString* pArray = aAlgos.getConstArray();
955 0 : for (long i=0; i<nCount; i++)
956 : {
957 0 : OUString sAlg = pArray[i];
958 0 : OUString sUser = pColRes->GetTranslation( sAlg );
959 0 : m_pLbAlgorithm->InsertEntry( sUser, LISTBOX_APPEND );
960 0 : }
961 0 : m_pLbAlgorithm->SelectEntryPos( 0 ); // first entry is default
962 0 : m_pFtAlgorithm->Enable( nCount > 1 ); // enable only if there is a choice
963 0 : m_pLbAlgorithm->Enable( nCount > 1 ); // enable only if there is a choice
964 : }
965 :
966 0 : m_pLbAlgorithm->SetUpdateMode( true );
967 0 : return 0;
968 0 : }
969 :
970 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|