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