xref: /trunk/main/sc/source/ui/dbgui/tpsort.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 #undef SC_DLLIMPLEMENTATION
32 
33 
34 
35 #include <vcl/msgbox.hxx>
36 #include <i18npool/mslangid.hxx>
37 #include <svtools/collatorres.hxx>
38 #include <unotools/collatorwrapper.hxx>
39 #include <unotools/localedatawrapper.hxx>
40 #include <comphelper/processfactory.hxx>
41 
42 #include "scitems.hxx"
43 #include "uiitems.hxx"
44 #include "viewdata.hxx"
45 #include "document.hxx"
46 #include "global.hxx"
47 #include "dbcolect.hxx"
48 #include "userlist.hxx"
49 #include "rangeutl.hxx"
50 #include "scresid.hxx"
51 #include "sc.hrc"       // -> Slot IDs
52 #include "globstr.hrc"
53 
54 #include "sortdlg.hxx"
55 #include "sortdlg.hrc"
56 
57 #define _TPSORT_CXX
58 #include "tpsort.hxx"
59 #undef _TPSORT_CXX
60 
61 using namespace com::sun::star;
62 
63 // STATIC DATA -----------------------------------------------------------
64 
65 static sal_uInt16 pSortRanges[] =
66 {
67     SID_SORT,
68     SID_SORT,
69     0
70 };
71 
72 // -----------------------------------------------------------------------
73 
74 /*
75  * Da sich Einstellungen auf der zweiten TabPage (Optionen) auf
76  * die erste TabPage auswirken, muss es die Moeglichkeit geben,
77  * dies der jeweils anderen Seite mitzuteilen.
78  *
79  * Im Moment wird dieses Problem ueber zwei Datenmember des TabDialoges
80  * geloest. Wird eine Seite Aktiviert/Deaktiviert, so gleicht sie diese
81  * Datenmember mit dem eigenen Zustand ab (->Activate()/Deactivate()).
82  *
83  * 31.01.95:
84  * Die Klasse SfxTabPage bietet mittlerweile ein Verfahren an:
85  *
86  * virtual sal_Bool HasExchangeSupport() const; -> return sal_True;
87  * virtual void ActivatePage(const SfxItemSet &);
88  * virtual int  DeactivatePage(SfxItemSet * = 0);
89  *
90  * muss noch geaendert werden!
91  */
92 
93 //========================================================================
94 //========================================================================
95 // Sortierkriterien-Tabpage:
96 
97 ScTabPageSortFields::ScTabPageSortFields( Window*           pParent,
98                                           const SfxItemSet& rArgSet )
99 
100     :   SfxTabPage      ( pParent,
101                           ScResId( RID_SCPAGE_SORT_FIELDS ),
102                           rArgSet ),
103         //
104         aFlSort1        ( this, ScResId( FL_SORT1  ) ),
105         aLbSort1        ( this, ScResId( LB_SORT1  ) ),
106         aBtnUp1         ( this, ScResId( BTN_UP1   ) ),
107         aBtnDown1       ( this, ScResId( BTN_DOWN1 ) ),
108         //
109         aFlSort2        ( this, ScResId( FL_SORT2  ) ),
110         aLbSort2        ( this, ScResId( LB_SORT2  ) ),
111         aBtnUp2         ( this, ScResId( BTN_UP2   ) ),
112         aBtnDown2       ( this, ScResId( BTN_DOWN2 ) ),
113         //
114         aFlSort3        ( this, ScResId( FL_SORT3  ) ),
115         aLbSort3        ( this, ScResId( LB_SORT3  ) ),
116         aBtnUp3         ( this, ScResId( BTN_UP3   ) ),
117         aBtnDown3       ( this, ScResId( BTN_DOWN3 ) ),
118 
119         aStrUndefined   ( ScResId( SCSTR_UNDEFINED ) ),
120         aStrColumn      ( ScResId( SCSTR_COLUMN ) ),
121         aStrRow         ( ScResId( SCSTR_ROW ) ),
122         //
123         nWhichSort      ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
124         pDlg            ( (ScSortDlg*)(GetParent()->GetParent()) ),
125         pViewData       ( NULL ),
126         rSortData       ( ((const ScSortItem&)
127                            rArgSet.Get( nWhichSort )).
128                                 GetSortData() ),
129         nFieldCount     ( 0 ),
130         bHasHeader      ( sal_False ),
131         bSortByRows     ( sal_False )
132 {
133     Init();
134     FreeResource();
135     SetExchangeSupport();
136 }
137 
138 // -----------------------------------------------------------------------
139 
140 __EXPORT ScTabPageSortFields::~ScTabPageSortFields()
141 {
142 }
143 
144 // -----------------------------------------------------------------------
145 
146 void ScTabPageSortFields::Init()
147 {
148     const ScSortItem& rSortItem = (const ScSortItem&)
149                                   GetItemSet().Get( nWhichSort );
150 
151     pViewData = rSortItem.GetViewData();
152 
153     DBG_ASSERT( pViewData, "ViewData not found!" );
154 
155     nFieldArr[0] = 0;
156     nFirstCol = 0;
157     nFirstRow = 0;
158 
159     aLbSort1.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
160     aLbSort2.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
161     aLbSort3.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
162     aLbSort1.Clear();
163     aLbSort2.Clear();
164     aLbSort3.Clear();
165 
166     aSortLbArr[0]       = &aLbSort1;
167     aSortLbArr[1]       = &aLbSort2;
168     aSortLbArr[2]       = &aLbSort3;
169     aDirBtnArr[0][0]    = &aBtnUp1;
170     aDirBtnArr[0][1]    = &aBtnDown1;
171     aDirBtnArr[1][0]    = &aBtnUp2;
172     aDirBtnArr[1][1]    = &aBtnDown2;
173     aDirBtnArr[2][0]    = &aBtnUp3;
174     aDirBtnArr[2][1]    = &aBtnDown3;
175     aFlArr[0]           = &aFlSort1;
176     aFlArr[1]           = &aFlSort2;
177     aFlArr[2]           = &aFlSort3;
178 }
179 
180 //------------------------------------------------------------------------
181 
182 sal_uInt16* __EXPORT ScTabPageSortFields::GetRanges()
183 {
184     return pSortRanges;
185 }
186 
187 // -----------------------------------------------------------------------
188 
189 SfxTabPage* __EXPORT ScTabPageSortFields::Create( Window*   pParent,
190                                          const SfxItemSet&  rArgSet )
191 {
192     return ( new ScTabPageSortFields( pParent, rArgSet ) );
193 }
194 
195 // -----------------------------------------------------------------------
196 
197 void __EXPORT ScTabPageSortFields::Reset( const SfxItemSet& /* rArgSet */ )
198 {
199     bSortByRows = rSortData.bByRow;
200     bHasHeader  = rSortData.bHasHeader;
201 
202     if ( aLbSort1.GetEntryCount() == 0 )
203         FillFieldLists();
204 
205     // Selektieren der ListBoxen:
206 
207     if ( rSortData.bDoSort[0] )
208     {
209         for ( sal_uInt16 i=0; i<3; i++ )
210         {
211             if ( rSortData.bDoSort[i] )
212             {
213                 aSortLbArr[i]->SelectEntryPos(
214                      GetFieldSelPos( rSortData.nField[i] ) );
215 
216                 (rSortData.bAscending[i])
217                     ? aDirBtnArr[i][0]->Check()     // Up
218                     : aDirBtnArr[i][1]->Check();    // Down
219             }
220             else
221             {
222                 aSortLbArr[i]->SelectEntryPos( 0 ); // "keiner" selektieren
223                 aDirBtnArr[i][0]->Check();          // Up
224             }
225         }
226 
227         EnableField( 1 );
228         EnableField( 2 );
229         EnableField( 3 );
230         if ( aLbSort1.GetSelectEntryPos() == 0 )
231             DisableField( 2 );
232         if ( aLbSort2.GetSelectEntryPos() == 0 )
233             DisableField( 3 );
234     }
235     else
236     {
237         SCCOL  nCol = pViewData->GetCurX();
238 
239         if( nCol < rSortData.nCol1 )
240             nCol = rSortData.nCol1;
241         else if( nCol > rSortData.nCol2 )
242             nCol = rSortData.nCol2;
243 
244         sal_uInt16  nSort1Pos = nCol - rSortData.nCol1+1;
245         aLbSort1.SelectEntryPos( nSort1Pos );
246         aLbSort2.SelectEntryPos( 0 );
247         aLbSort3.SelectEntryPos( 0 );
248         aBtnUp1.Check();
249         aBtnUp2.Check();
250         aBtnUp3.Check();
251         EnableField ( 1 );
252         EnableField ( 2 );
253         DisableField( 3 );
254     }
255 
256     if ( pDlg )
257     {
258         pDlg->SetByRows ( bSortByRows );
259         pDlg->SetHeaders( bHasHeader );
260     }
261 }
262 
263 // -----------------------------------------------------------------------
264 
265 sal_Bool __EXPORT ScTabPageSortFields::FillItemSet( SfxItemSet& rArgSet )
266 {
267     ScSortParam theSortData = rSortData;
268     if (pDlg)
269     {
270         const SfxItemSet* pExample = pDlg->GetExampleSet();
271         const SfxPoolItem* pItem;
272         if ( pExample && pExample->GetItemState( nWhichSort, sal_True, &pItem ) == SFX_ITEM_SET )
273             theSortData = ((const ScSortItem*)pItem)->GetSortData();
274     }
275 
276     sal_uInt16  nSort1Pos = aLbSort1.GetSelectEntryPos();
277     sal_uInt16  nSort2Pos = aLbSort2.GetSelectEntryPos();
278     sal_uInt16  nSort3Pos = aLbSort3.GetSelectEntryPos();
279 
280     DBG_ASSERT(    (nSort1Pos <= SC_MAXFIELDS)
281                 && (nSort2Pos <= SC_MAXFIELDS)
282                 && (nSort3Pos <= SC_MAXFIELDS),
283                 "Array-Range Fehler!" );
284 
285     if ( nSort1Pos == LISTBOX_ENTRY_NOTFOUND ) nSort1Pos = 0;
286     if ( nSort2Pos == LISTBOX_ENTRY_NOTFOUND ) nSort2Pos = 0;
287     if ( nSort3Pos == LISTBOX_ENTRY_NOTFOUND ) nSort3Pos = 0;
288 
289     if ( nSort1Pos > 0 )
290     {
291         theSortData.bDoSort[0] = (nSort1Pos > 0);
292         theSortData.bDoSort[1] = (nSort2Pos > 0);
293         theSortData.bDoSort[2] = (nSort3Pos > 0);
294 
295         // wenn auf Optionen-Seite "OK" gewaehlt wurde und
296         // dabei die Sortierrichtung umgestellt wurde, so
297         // wird das erste Feld der jeweiligen Richtung als
298         // Sortierkriterium gewaehlt (steht in nFieldArr[0]):
299         if ( bSortByRows != pDlg->GetByRows() )
300         {
301             theSortData.nField[0] =
302             theSortData.nField[1] =
303             theSortData.nField[2] = ( bSortByRows ?
304                     static_cast<SCCOLROW>(nFirstRow) :
305                     static_cast<SCCOLROW>(nFirstCol) );
306         }
307         else
308         {
309             theSortData.nField[0] = nFieldArr[nSort1Pos];
310             theSortData.nField[1] = nFieldArr[nSort2Pos];
311             theSortData.nField[2] = nFieldArr[nSort3Pos];
312         }
313 
314         theSortData.bAscending[0] = aBtnUp1.IsChecked();
315         theSortData.bAscending[1] = aBtnUp2.IsChecked();
316         theSortData.bAscending[2] = aBtnUp3.IsChecked();
317         //  bHasHeader ist in ScTabPageSortOptions::FillItemSet, wo es hingehoert
318     }
319     else
320     {
321         theSortData.bDoSort[0] =
322         theSortData.bDoSort[1] =
323         theSortData.bDoSort[2] = sal_False;
324     }
325 
326     rArgSet.Put( ScSortItem( SCITEM_SORTDATA, NULL, &theSortData ) );
327 
328     return sal_True;
329 }
330 
331 // -----------------------------------------------------------------------
332 
333 // fuer Datenaustausch ohne Dialog-Umweg: (! noch zu tun !)
334 // void ScTabPageSortFields::ActivatePage( const SfxItemSet& rSet )
335 
336 void __EXPORT ScTabPageSortFields::ActivatePage()
337 {
338     if ( pDlg )
339     {
340         if (   bHasHeader  != pDlg->GetHeaders()
341             || bSortByRows != pDlg->GetByRows()   )
342         {
343             sal_uInt16  nCurSel1 = aLbSort1.GetSelectEntryPos();
344             sal_uInt16  nCurSel2 = aLbSort2.GetSelectEntryPos();
345             sal_uInt16  nCurSel3 = aLbSort3.GetSelectEntryPos();
346 
347             bHasHeader  = pDlg->GetHeaders();
348             bSortByRows = pDlg->GetByRows();
349             FillFieldLists();
350             aLbSort1.SelectEntryPos( nCurSel1 );
351             aLbSort2.SelectEntryPos( nCurSel2 );
352             aLbSort3.SelectEntryPos( nCurSel3 );
353         }
354     }
355 }
356 
357 // -----------------------------------------------------------------------
358 
359 int __EXPORT ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
360 {
361     if ( pDlg )
362     {
363         if ( bHasHeader != pDlg->GetHeaders() )
364             pDlg->SetHeaders( bHasHeader );
365 
366         if ( bSortByRows != pDlg->GetByRows() )
367             pDlg->SetByRows( bSortByRows );
368     }
369 
370     if ( pSetP )
371         FillItemSet( *pSetP );
372 
373     return SfxTabPage::LEAVE_PAGE;
374 }
375 
376 // -----------------------------------------------------------------------
377 
378 void ScTabPageSortFields::DisableField( sal_uInt16 nField )
379 {
380     nField--;
381 
382     if ( nField<=2 )
383     {
384         aSortLbArr[nField]   ->Disable();
385         aDirBtnArr[nField][0]->Disable();
386         aDirBtnArr[nField][1]->Disable();
387         aFlArr[nField]       ->Disable();
388     }
389 }
390 
391 // -----------------------------------------------------------------------
392 
393 void ScTabPageSortFields::EnableField( sal_uInt16 nField )
394 {
395     nField--;
396 
397     if ( nField<=2 )
398     {
399         aSortLbArr[nField]   ->Enable();
400         aDirBtnArr[nField][0]->Enable();
401         aDirBtnArr[nField][1]->Enable();
402         aFlArr[nField]       ->Enable();
403     }
404 }
405 
406 // -----------------------------------------------------------------------
407 
408 void ScTabPageSortFields::FillFieldLists()
409 {
410     if ( pViewData )
411     {
412         ScDocument* pDoc = pViewData->GetDocument();
413 
414         if ( pDoc )
415         {
416             aLbSort1.Clear();
417             aLbSort2.Clear();
418             aLbSort3.Clear();
419             aLbSort1.InsertEntry( aStrUndefined, 0 );
420             aLbSort2.InsertEntry( aStrUndefined, 0 );
421             aLbSort3.InsertEntry( aStrUndefined, 0 );
422 
423             SCCOL   nFirstSortCol   = rSortData.nCol1;
424             SCROW   nFirstSortRow   = rSortData.nRow1;
425             SCTAB   nTab        = pViewData->GetTabNo();
426             sal_uInt16  i           = 1;
427 
428             if ( bSortByRows )
429             {
430                 String  aFieldName;
431                 SCCOL   nMaxCol = rSortData.nCol2;
432                 SCCOL   col;
433 
434                 for ( col=nFirstSortCol; col<=nMaxCol && i<SC_MAXFIELDS; col++ )
435                 {
436                     pDoc->GetString( col, nFirstSortRow, nTab, aFieldName );
437                     if ( !bHasHeader || (aFieldName.Len() == 0) )
438                     {
439                         aFieldName  = aStrColumn;
440                         aFieldName += ' ';
441                         aFieldName += ScColToAlpha( col );
442                     }
443                     nFieldArr[i] = col;
444                     aLbSort1.InsertEntry( aFieldName, i );
445                     aLbSort2.InsertEntry( aFieldName, i );
446                     aLbSort3.InsertEntry( aFieldName, i );
447                     i++;
448                 }
449             }
450             else
451             {
452                 String  aFieldName;
453                 SCROW   nMaxRow = rSortData.nRow2;
454                 SCROW   row;
455 
456                 for ( row=nFirstSortRow; row<=nMaxRow && i<SC_MAXFIELDS; row++ )
457                 {
458                     pDoc->GetString( nFirstSortCol, row, nTab, aFieldName );
459                     if ( !bHasHeader || (aFieldName.Len() == 0) )
460                     {
461                         aFieldName  = aStrRow;
462                         aFieldName += ' ';
463                         aFieldName += String::CreateFromInt32( row+1 );
464                     }
465                     nFieldArr[i] = row;
466                     aLbSort1.InsertEntry( aFieldName, i );
467                     aLbSort2.InsertEntry( aFieldName, i );
468                     aLbSort3.InsertEntry( aFieldName, i );
469                     i++;
470                 }
471             }
472             nFieldCount = i;
473         }
474     }
475 }
476 
477 //------------------------------------------------------------------------
478 
479 sal_uInt16 ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
480 {
481     sal_uInt16  nFieldPos   = 0;
482     sal_Bool    bFound      = sal_False;
483 
484     for ( sal_uInt16 n=1; n<nFieldCount && !bFound; n++ )
485     {
486         if ( nFieldArr[n] == nField )
487         {
488             nFieldPos = n;
489             bFound = sal_True;
490         }
491     }
492 
493     return nFieldPos;
494 }
495 
496 // -----------------------------------------------------------------------
497 // Handler:
498 //---------
499 
500 IMPL_LINK( ScTabPageSortFields, SelectHdl, ListBox *, pLb )
501 {
502     String aSelEntry = pLb->GetSelectEntry();
503 
504     if ( pLb == &aLbSort1 )
505     {
506         if ( aSelEntry == aStrUndefined )
507         {
508             aLbSort2.SelectEntryPos( 0 );
509             aLbSort3.SelectEntryPos( 0 );
510 
511             if ( aFlSort2.IsEnabled() )
512                 DisableField( 2 );
513 
514             if ( aFlSort3.IsEnabled() )
515                 DisableField( 3 );
516         }
517         else
518         {
519             if ( !aFlSort2.IsEnabled() )
520                 EnableField( 2 );
521         }
522     }
523     else if ( pLb == &aLbSort2 )
524     {
525         if ( aSelEntry == aStrUndefined )
526         {
527             aLbSort3.SelectEntryPos( 0 );
528             if ( aFlSort3.IsEnabled() )
529                 DisableField( 3 );
530         }
531         else
532         {
533             if ( !aFlSort3.IsEnabled() )
534                 EnableField( 3 );
535         }
536     }
537     return 0;
538 }
539 
540 //========================================================================
541 // Sortieroptionen-Tabpage:
542 //========================================================================
543 
544 #if ENABLE_LAYOUT_EXPERIMENTAL
545 #include <layout/layout-pre.hxx>
546 
547 #if ENABLE_LAYOUT
548 #undef ScResId
549 #define ScResId(x) #x
550 #undef SfxTabPage
551 #define SfxTabPage( parent, id, args ) SfxTabPage( parent, "sort-options.xml", id, &args )
552 #endif /* ENABLE_LAYOUT */
553 
554 #endif /* ENABLE_LAYOUT_EXPERIMENTAL */
555 
556 ScTabPageSortOptions::ScTabPageSortOptions( Window*             pParent,
557                                             const SfxItemSet&   rArgSet )
558 
559     :   SfxTabPage      ( pParent,
560                           ScResId( RID_SCPAGE_SORT_OPTIONS ),
561                           rArgSet ),
562         //
563         aBtnCase        ( this, ScResId( BTN_CASESENSITIVE ) ),
564         aBtnHeader      ( this, ScResId( BTN_LABEL ) ),
565         aBtnFormats     ( this, ScResId( BTN_FORMATS ) ),
566         aBtnCopyResult  ( this, ScResId( BTN_COPYRESULT ) ),
567         aLbOutPos       ( this, ScResId( LB_OUTAREA ) ),
568         aEdOutPos       ( this, ScResId( ED_OUTAREA ) ),
569         aBtnSortUser    ( this, ScResId( BTN_SORT_USER ) ),
570         aLbSortUser     ( this, ScResId( LB_SORT_USER ) ),
571         aFtLanguage     ( this, ScResId( FT_LANGUAGE ) ),
572         aLbLanguage     ( this, ScResId( LB_LANGUAGE ) ),
573         aFtAlgorithm    ( this, ScResId( FT_ALGORITHM ) ),
574         aLbAlgorithm    ( this, ScResId( LB_ALGORITHM ) ),
575         aLineDirection  ( this, ScResId( FL_DIRECTION ) ),
576         aBtnTopDown     ( this, ScResId( BTN_TOP_DOWN ) ),
577         aBtnLeftRight   ( this, ScResId( BTN_LEFT_RIGHT ) ),
578         aFtAreaLabel    ( this, ScResId( FT_AREA_LABEL ) ),
579 //      aFtArea         ( this, ScResId( FT_AREA ) ),
580         //
581 #if ENABLE_LAYOUT_EXPERIMENTAL
582 #undef this
583 #undef ScResId
584 #define ScResId(x) this, #x
585 #endif /* ENABLE_LAYOUT_EXPERIMENTAL */
586         aStrRowLabel    ( ScResId( STR_ROW_LABEL ) ),
587         aStrColLabel    ( ScResId( STR_COL_LABEL ) ),
588         aStrUndefined   ( ScResId( SCSTR_UNDEFINED ) ),
589         aStrNoName      ( ScGlobal::GetRscString(STR_DB_NONAME) ),
590         //
591         nWhichSort      ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
592         rSortData       ( ((const ScSortItem&)
593                           rArgSet.Get( nWhichSort )).GetSortData() ),
594         pViewData       ( NULL ),
595         pDoc            ( NULL ),
596         pDlg            ( (ScSortDlg*)(GetParent() ? GetParent()->GetParent() : 0 ) ),
597         pColRes         ( NULL ),
598         pColWrap        ( NULL )
599 {
600     Init();
601     FreeResource();
602     SetExchangeSupport();
603 
604     aLbOutPos.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
605     aLbOutPos.SetAccessibleName(aBtnCopyResult.GetText());
606     aEdOutPos.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
607     aEdOutPos.SetAccessibleName(aBtnCopyResult.GetText());
608     aLbSortUser.SetAccessibleRelationLabeledBy(&aBtnSortUser);
609     aLbSortUser.SetAccessibleName(aBtnSortUser.GetText());
610 }
611 
612 // -----------------------------------------------------------------------
613 
614 __EXPORT ScTabPageSortOptions::~ScTabPageSortOptions()
615 {
616     sal_uInt16 nEntries = aLbOutPos.GetEntryCount();
617 
618     for ( sal_uInt16 i=1; i<nEntries; i++ )
619         delete (String*)aLbOutPos.GetEntryData( i );
620 
621     delete pColRes;
622     delete pColWrap;        //! not if from document
623 }
624 
625 // -----------------------------------------------------------------------
626 
627 void ScTabPageSortOptions::Init()
628 {
629     aStrAreaLabel = aFtAreaLabel.GetText();
630     aStrAreaLabel.Append( (sal_Unicode) ' ' );
631 
632     //  CollatorRessource has user-visible names for sort algorithms
633     pColRes = new CollatorRessource();
634 
635     //! use CollatorWrapper from document?
636     pColWrap = new CollatorWrapper( comphelper::getProcessServiceFactory() );
637 
638     const ScSortItem&   rSortItem = (const ScSortItem&)
639                                     GetItemSet().Get( nWhichSort );
640 
641     aLbOutPos.SetSelectHdl    ( LINK( this, ScTabPageSortOptions, SelOutPosHdl ) );
642     aBtnCopyResult.SetClickHdl( LINK( this, ScTabPageSortOptions, EnableHdl ) );
643     aBtnSortUser.SetClickHdl  ( LINK( this, ScTabPageSortOptions, EnableHdl ) );
644     aBtnTopDown.SetClickHdl   ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
645     aBtnLeftRight.SetClickHdl ( LINK( this, ScTabPageSortOptions, SortDirHdl ) );
646     aLbLanguage.SetSelectHdl  ( LINK( this, ScTabPageSortOptions, FillAlgorHdl ) );
647 
648     pViewData = rSortItem.GetViewData();
649     pDoc      = pViewData ? pViewData->GetDocument() : NULL;
650 
651     DBG_ASSERT( pViewData, "ViewData not found! :-/" );
652 
653     if ( pViewData && pDoc )
654     {
655         String          theArea;
656         ScDBCollection* pDBColl     = pDoc->GetDBCollection();
657         String          theDbArea;
658         String          theDbName   = aStrNoName;
659         const SCTAB nCurTab     = pViewData->GetTabNo();
660         const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
661 
662         aLbOutPos.Clear();
663         aLbOutPos.InsertEntry( aStrUndefined, 0 );
664         aLbOutPos.Disable();
665 
666         ScAreaNameIterator aIter( pDoc );
667         String aName;
668         ScRange aRange;
669         String aRefStr;
670         while ( aIter.Next( aName, aRange ) )
671         {
672             sal_uInt16 nInsert = aLbOutPos.InsertEntry( aName );
673 
674             aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, eConv );
675             aLbOutPos.SetEntryData( nInsert, new String( aRefStr ) );
676         }
677 
678         aLbOutPos.SelectEntryPos( 0 );
679         aEdOutPos.SetText( EMPTY_STRING );
680 
681         /*
682          * Ueberpruefen, ob es sich bei dem uebergebenen
683          * Bereich um einen Datenbankbereich handelt:
684          */
685 
686         ScAddress aScAddress( rSortData.nCol1, rSortData.nRow1, nCurTab );
687         ScRange( aScAddress,
688                  ScAddress( rSortData.nCol2, rSortData.nRow2, nCurTab )
689                ).Format( theArea, SCR_ABS, pDoc, eConv );
690 
691         if ( pDBColl )
692         {
693             ScDBData* pDBData
694                     = pDBColl->GetDBAtArea( nCurTab,
695                                             rSortData.nCol1, rSortData.nRow1,
696                                             rSortData.nCol2, rSortData.nRow2 );
697             if ( pDBData )
698             {
699                 pDBData->GetName( theDbName );
700                 aBtnHeader.Check( pDBData->HasHeader() );
701             }
702         }
703 
704         theArea.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" ("));
705         theArea += theDbName;
706         theArea += ')';
707 
708         //aFtArea.SetText( theArea );
709         theArea.Insert( aStrAreaLabel, 0 );
710         aFtAreaLabel.SetText( theArea );
711 
712         aBtnHeader.SetText( aStrColLabel );
713     }
714 
715     FillUserSortListBox();
716 
717     //  get available languages
718 
719     aLbLanguage.SetLanguageList( LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, sal_False );
720     aLbLanguage.InsertLanguage( LANGUAGE_SYSTEM );
721 }
722 
723 //------------------------------------------------------------------------
724 
725 sal_uInt16* __EXPORT ScTabPageSortOptions::GetRanges()
726 {
727     return pSortRanges;
728 }
729 
730 // -----------------------------------------------------------------------
731 
732 #if ENABLE_LAYOUT_EXPERIMENTAL
733 #undef SfxTabPage
734 #endif /* ENABLE_LAYOUT_EXPERIMENTAL */
735 SfxTabPage* __EXPORT ScTabPageSortOptions::Create(
736                                             Window*             pParent,
737                                             const SfxItemSet&   rArgSet )
738 {
739     return ( new ScTabPageSortOptions( pParent, rArgSet ) );
740 }
741 
742 // -----------------------------------------------------------------------
743 
744 void __EXPORT ScTabPageSortOptions::Reset( const SfxItemSet& /* rArgSet */ )
745 {
746     if ( rSortData.bUserDef )
747     {
748         aBtnSortUser.Check( sal_True );
749         aLbSortUser.Enable();
750         aLbSortUser.SelectEntryPos( rSortData.nUserIndex );
751     }
752     else
753     {
754         aBtnSortUser.Check( sal_False );
755         aLbSortUser.Disable();
756         aLbSortUser.SelectEntryPos( 0 );
757     }
758 
759     aBtnCase.Check      ( rSortData.bCaseSens );
760     aBtnFormats.Check   ( rSortData.bIncludePattern );
761     aBtnHeader.Check    ( rSortData.bHasHeader );
762 
763     if ( rSortData.bByRow )
764     {
765         aBtnTopDown.Check();
766         aBtnHeader.SetText( aStrColLabel );
767     }
768     else
769     {
770         aBtnLeftRight.Check();
771         aBtnHeader.SetText( aStrRowLabel );
772     }
773 
774     LanguageType eLang = MsLangId::convertLocaleToLanguage( rSortData.aCollatorLocale );
775     if ( eLang == LANGUAGE_DONTKNOW )
776         eLang = LANGUAGE_SYSTEM;
777     aLbLanguage.SelectLanguage( eLang );
778     FillAlgorHdl( &aLbLanguage );               // get algorithms, select default
779     if ( rSortData.aCollatorAlgorithm.Len() )
780         aLbAlgorithm.SelectEntry( pColRes->GetTranslation( rSortData.aCollatorAlgorithm ) );
781 
782     if ( pDoc && !rSortData.bInplace )
783     {
784         String aStr;
785         sal_uInt16 nFormat = (rSortData.nDestTab != pViewData->GetTabNo())
786                             ? SCR_ABS_3D
787                             : SCR_ABS;
788 
789         theOutPos.Set( rSortData.nDestCol,
790                        rSortData.nDestRow,
791                        rSortData.nDestTab );
792 
793         theOutPos.Format( aStr, nFormat, pDoc, pDoc->GetAddressConvention() );
794         aBtnCopyResult.Check();
795         aLbOutPos.Enable();
796         aEdOutPos.Enable();
797         aEdOutPos.SetText( aStr );
798         EdOutPosModHdl( &aEdOutPos );
799         aEdOutPos.GrabFocus();
800         aEdOutPos.SetSelection( Selection( 0, SELECTION_MAX ) );
801     }
802     else
803     {
804         aBtnCopyResult.Check( sal_False );
805         aLbOutPos.Disable();
806         aEdOutPos.Disable();
807         aEdOutPos.SetText( EMPTY_STRING );
808     }
809 }
810 
811 // -----------------------------------------------------------------------
812 
813 sal_Bool __EXPORT ScTabPageSortOptions::FillItemSet( SfxItemSet& rArgSet )
814 {
815     ScSortParam theSortData = rSortData;
816     if (pDlg)
817     {
818         const SfxItemSet* pExample = pDlg->GetExampleSet();
819         const SfxPoolItem* pItem;
820         if ( pExample && pExample->GetItemState( nWhichSort, sal_True, &pItem ) == SFX_ITEM_SET )
821             theSortData = ((const ScSortItem*)pItem)->GetSortData();
822     }
823 
824     theSortData.bByRow          = aBtnTopDown.IsChecked();
825     theSortData.bHasHeader      = aBtnHeader.IsChecked();
826     theSortData.bCaseSens       = aBtnCase.IsChecked();
827     theSortData.bIncludePattern = aBtnFormats.IsChecked();
828     theSortData.bInplace        = !aBtnCopyResult.IsChecked();
829     theSortData.nDestCol        = theOutPos.Col();
830     theSortData.nDestRow        = theOutPos.Row();
831     theSortData.nDestTab        = theOutPos.Tab();
832     theSortData.bUserDef        = aBtnSortUser.IsChecked();
833     theSortData.nUserIndex      = (aBtnSortUser.IsChecked())
834                                     ? aLbSortUser.GetSelectEntryPos()
835                                     : 0;
836 
837     // get locale
838     LanguageType eLang = aLbLanguage.GetSelectLanguage();
839     theSortData.aCollatorLocale = MsLangId::convertLanguageToLocale( eLang, false );
840 
841     // get algorithm
842     String sAlg;
843     if ( eLang != LANGUAGE_SYSTEM )
844     {
845         uno::Sequence<rtl::OUString> aAlgos = pColWrap->listCollatorAlgorithms(
846                 theSortData.aCollatorLocale );
847         sal_uInt16 nSel = aLbAlgorithm.GetSelectEntryPos();
848         if ( nSel < aAlgos.getLength() )
849             sAlg = aAlgos[nSel];
850     }
851     theSortData.aCollatorAlgorithm = sAlg;
852 
853     rArgSet.Put( ScSortItem( SCITEM_SORTDATA, &theSortData ) );
854 
855     return sal_True;
856 }
857 
858 // -----------------------------------------------------------------------
859 
860 // fuer Datenaustausch ohne Dialog-Umweg: (! noch zu tun !)
861 // void ScTabPageSortOptions::ActivatePage( const SfxItemSet& rSet )
862 void __EXPORT ScTabPageSortOptions::ActivatePage()
863 {
864     if ( pDlg )
865     {
866         if ( aBtnHeader.IsChecked() != pDlg->GetHeaders() )
867         {
868             aBtnHeader.Check( pDlg->GetHeaders() );
869         }
870 
871         if ( aBtnTopDown.IsChecked() != pDlg->GetByRows() )
872         {
873             aBtnTopDown.Check( pDlg->GetByRows() );
874             aBtnLeftRight.Check( !pDlg->GetByRows() );
875         }
876 
877         aBtnHeader.SetText( (pDlg->GetByRows())
878                             ? aStrColLabel
879                             : aStrRowLabel );
880     }
881 }
882 
883 // -----------------------------------------------------------------------
884 
885 int __EXPORT ScTabPageSortOptions::DeactivatePage( SfxItemSet* pSetP )
886 {
887     sal_Bool bPosInputOk = sal_True;
888 
889     if ( aBtnCopyResult.IsChecked() )
890     {
891         String      thePosStr = aEdOutPos.GetText();
892         ScAddress   thePos;
893         xub_StrLen  nColonPos = thePosStr.Search( ':' );
894 
895         if ( STRING_NOTFOUND != nColonPos )
896             thePosStr.Erase( nColonPos );
897 
898         if ( pViewData )
899         {
900             //  visible table is default for input without table
901             //  must be changed to GetRefTabNo when sorting has RefInput!
902             thePos.SetTab( pViewData->GetTabNo() );
903         }
904 
905         sal_uInt16 nResult = thePos.Parse( thePosStr, pDoc, pDoc->GetAddressConvention() );
906 
907         bPosInputOk = ( SCA_VALID == (nResult & SCA_VALID) );
908 
909         if ( !bPosInputOk )
910         {
911 #if !ENABLE_LAYOUT_EXPERIMENTAL
912             ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ),
913                      ScGlobal::GetRscString( STR_INVALID_TABREF )
914                     ).Execute();
915 #endif /* ENABLE_LAYOUT_EXPERIMENTAL */
916             aEdOutPos.GrabFocus();
917             aEdOutPos.SetSelection( Selection( 0, SELECTION_MAX ) );
918             theOutPos.Set(0,0,0);
919         }
920         else
921         {
922             aEdOutPos.SetText( thePosStr );
923             theOutPos = thePos;
924         }
925     }
926 
927     if ( pDlg && bPosInputOk )
928     {
929         pDlg->SetHeaders( aBtnHeader.IsChecked() );
930         pDlg->SetByRows ( aBtnTopDown.IsChecked() );
931     }
932 
933     if ( pSetP && bPosInputOk )
934         FillItemSet( *pSetP );
935 
936     return bPosInputOk ? SfxTabPage::LEAVE_PAGE : SfxTabPage::KEEP_PAGE;
937 }
938 
939 // -----------------------------------------------------------------------
940 
941 void ScTabPageSortOptions::FillUserSortListBox()
942 {
943     ScUserList* pUserLists = ScGlobal::GetUserList();
944 
945     aLbSortUser.Clear();
946     if ( pUserLists )
947     {
948         sal_uInt16 nCount = pUserLists->GetCount();
949         if ( nCount > 0 )
950             for ( sal_uInt16 i=0; i<nCount; i++ )
951                 aLbSortUser.InsertEntry( (*pUserLists)[i]->GetString() );
952     }
953 }
954 
955 // -----------------------------------------------------------------------
956 // Handler:
957 
958 IMPL_LINK( ScTabPageSortOptions, EnableHdl, CheckBox *, pBox )
959 {
960     if ( pBox == &aBtnCopyResult )
961     {
962         if ( pBox->IsChecked() )
963         {
964             aLbOutPos.Enable();
965             aEdOutPos.Enable();
966             aEdOutPos.GrabFocus();
967         }
968         else
969         {
970             aLbOutPos.Disable();
971             aEdOutPos.Disable();
972         }
973     }
974     else if ( pBox == &aBtnSortUser )
975     {
976         if ( pBox->IsChecked() )
977         {
978             aLbSortUser.Enable();
979             aLbSortUser.GrabFocus();
980         }
981         else
982             aLbSortUser.Disable();
983     }
984     return 0;
985 }
986 
987 // -----------------------------------------------------------------------
988 
989 IMPL_LINK( ScTabPageSortOptions, SelOutPosHdl, ListBox *, pLb )
990 {
991     if ( pLb == &aLbOutPos )
992     {
993         String  aString;
994         sal_uInt16  nSelPos = aLbOutPos.GetSelectEntryPos();
995 
996         if ( nSelPos > 0 )
997             aString = *(String*)aLbOutPos.GetEntryData( nSelPos );
998 
999         aEdOutPos.SetText( aString );
1000     }
1001     return 0;
1002 }
1003 
1004 // -----------------------------------------------------------------------
1005 
1006 IMPL_LINK( ScTabPageSortOptions, SortDirHdl, RadioButton *, pBtn )
1007 {
1008     if ( pBtn == &aBtnTopDown )
1009     {
1010         aBtnHeader.SetText( aStrColLabel );
1011     }
1012     else if ( pBtn == &aBtnLeftRight )
1013     {
1014         aBtnHeader.SetText( aStrRowLabel );
1015     }
1016     return 0;
1017 }
1018 
1019 // -----------------------------------------------------------------------
1020 
1021 void __EXPORT ScTabPageSortOptions::EdOutPosModHdl( Edit* pEd )
1022 {
1023     if ( pEd == &aEdOutPos )
1024     {
1025         String  theCurPosStr = aEdOutPos.GetText();
1026         sal_uInt16  nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
1027 
1028         if ( SCA_VALID == (nResult & SCA_VALID) )
1029         {
1030             String* pStr    = NULL;
1031             sal_Bool    bFound  = sal_False;
1032             sal_uInt16  i       = 0;
1033             sal_uInt16  nCount  = aLbOutPos.GetEntryCount();
1034 
1035             for ( i=2; i<nCount && !bFound; i++ )
1036             {
1037                 pStr = (String*)aLbOutPos.GetEntryData( i );
1038                 bFound = (theCurPosStr == *pStr);
1039             }
1040 
1041             if ( bFound )
1042                 aLbOutPos.SelectEntryPos( --i );
1043             else
1044                 aLbOutPos.SelectEntryPos( 0 );
1045         }
1046     }
1047 }
1048 
1049 // -----------------------------------------------------------------------
1050 
1051 IMPL_LINK( ScTabPageSortOptions, FillAlgorHdl, void *, EMPTYARG )
1052 {
1053     aLbAlgorithm.SetUpdateMode( sal_False );
1054     aLbAlgorithm.Clear();
1055 
1056     LanguageType eLang = aLbLanguage.GetSelectLanguage();
1057     if ( eLang == LANGUAGE_SYSTEM )
1058     {
1059         //  for LANGUAGE_SYSTEM no algorithm can be selected because
1060         //  it wouldn't necessarily exist for other languages
1061         //  -> leave list box empty if LANGUAGE_SYSTEM is selected
1062         aFtAlgorithm.Enable( sal_False );           // nothing to select
1063         aLbAlgorithm.Enable( sal_False );           // nothing to select
1064     }
1065     else
1066     {
1067         lang::Locale aLocale( MsLangId::convertLanguageToLocale( eLang ));
1068         uno::Sequence<rtl::OUString> aAlgos = pColWrap->listCollatorAlgorithms( aLocale );
1069 
1070         long nCount = aAlgos.getLength();
1071         const rtl::OUString* pArray = aAlgos.getConstArray();
1072         for (long i=0; i<nCount; i++)
1073         {
1074             String sAlg = pArray[i];
1075             String sUser = pColRes->GetTranslation( sAlg );
1076             aLbAlgorithm.InsertEntry( sUser, LISTBOX_APPEND );
1077         }
1078         aLbAlgorithm.SelectEntryPos( 0 );       // first entry is default
1079         aFtAlgorithm.Enable( nCount > 1 );      // enable only if there is a choice
1080         aLbAlgorithm.Enable( nCount > 1 );      // enable only if there is a choice
1081     }
1082 
1083     aLbAlgorithm.SetUpdateMode( sal_True );
1084     return 0;
1085 }
1086 
1087 
1088