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