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