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