xref: /trunk/main/sw/source/ui/misc/srtdlg.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_sw.hxx"
30 #ifdef SW_DLLIMPLEMENTATION
31 #undef SW_DLLIMPLEMENTATION
32 #endif
33 
34 #include "srtdlg.hxx"
35 
36 #ifndef _MSGBOX_HXX //autogen
37 #include <vcl/msgbox.hxx>
38 #endif
39 #include <svl/intitem.hxx>
40 #include <svl/eitem.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <svx/svxids.hrc>
43 #include <editeng/unolingu.hxx>
44 #include <svx/svxdlg.hxx>
45 #include <svx/dialogs.hrc>
46 #include <unotools/collatorwrapper.hxx>
47 #include <svtools/collatorres.hxx>
48 #include <swwait.hxx>
49 #include <view.hxx>
50 #include <cmdid.h>
51 #include <wrtsh.hxx>
52 #include <misc.hrc>
53 #include <srtdlg.hrc>
54 #include <swtable.hxx>
55 #include <node.hxx>
56 #include <tblsel.hxx>
57 #include <sfx2/request.hxx>
58 
59 // sw/inc/tblsel.hxx
60 SV_IMPL_PTRARR( _FndBoxes, _FndBox* )
61 SV_IMPL_PTRARR( _FndLines, _FndLine* )
62 
63 static sal_Bool bCheck1 = sal_True;
64 static sal_Bool bCheck2 = sal_False;
65 static sal_Bool bCheck3 = sal_False;
66 
67 static sal_uInt16 nCol1 = 1;
68 static sal_uInt16 nCol2 = 1;
69 static sal_uInt16 nCol3 = 1;
70 
71 static sal_uInt16 nType1 = 0;
72 static sal_uInt16 nType2 = 0;
73 static sal_uInt16 nType3 = 0;
74 
75 static sal_uInt16 nLang = LANGUAGE_NONE;
76 
77 static sal_Bool   bAsc1  = sal_True;
78 static sal_Bool   bAsc2  = sal_True;
79 static sal_Bool   bAsc3  = sal_True;
80 static sal_Bool   bCol   = sal_False;
81 static sal_Bool   bCsSens= sal_False;
82 
83 static sal_Unicode    cDeli  = '\t';
84 
85 using namespace ::com::sun::star::lang;
86 using namespace ::com::sun::star::uno;
87 using ::rtl::OUString;
88 
89 
90 void lcl_ClearLstBoxAndDelUserData( ListBox& rLstBox )
91 {
92     void* pDel;
93     for( sal_uInt16 n = 0, nEnd = rLstBox.GetEntryCount(); n < nEnd; ++n )
94         if( 0 != ( pDel = rLstBox.GetEntryData( n )) )
95             delete (String*)pDel;
96     rLstBox.Clear();
97 }
98 
99 /*--------------------------------------------------------------------
100      Beschreibung:  Fuer Tabellenselektion sel. Zeilen und Spalten
101                     feststellen
102  --------------------------------------------------------------------*/
103 
104 
105 sal_Bool lcl_GetSelTbl( SwWrtShell &rSh, sal_uInt16& rX, sal_uInt16& rY )
106 {
107     const SwTableNode* pTblNd = rSh.IsCrsrInTbl();
108     if( !pTblNd )
109         return sal_False;
110 
111     _FndBox aFndBox( 0, 0 );
112 
113     // suche alle Boxen / Lines
114     {
115         SwSelBoxes aSelBoxes;
116         ::GetTblSel( rSh, aSelBoxes );
117         _FndPara aPara( aSelBoxes, &aFndBox );
118         const SwTable& rTbl = pTblNd->GetTable();
119         ((SwTableLines&)rTbl.GetTabLines()).ForEach( &_FndLineCopyCol, &aPara );
120     }
121     rX = aFndBox.GetLines().Count();
122     if( !rX )
123         return sal_False;
124 
125     rY = aFndBox.GetLines()[0]->GetBoxes().Count();
126     return sal_True;
127 }
128 
129 /*--------------------------------------------------------------------
130      Beschreibung: Init-Liste
131  --------------------------------------------------------------------*/
132 
133 SwSortDlg::SwSortDlg(Window* pParent, SwWrtShell &rShell) :
134 
135     SvxStandardDialog(pParent, SW_RES(DLG_SORTING)),
136 
137     aColLbl(this,       SW_RES(FT_COL   )),
138     aTypLbl(this,       SW_RES(FT_KEYTYP)),
139     aDirLbl(this,       SW_RES(FT_DIR   )),
140     aSortFL(this,      SW_RES(FL_SORT_2  )),
141 
142 
143     aKeyCB1(this,       SW_RES(CB_KEY1  )),
144     aColEdt1(this,      SW_RES(ED_KEY1  )),
145     aTypDLB1(this,      SW_RES(DLB_KEY1 )),
146     aSortUpRB(this,     SW_RES(RB_UP    )),
147     aSortDnRB(this,     SW_RES(RB_DN    )),
148 
149     aKeyCB2(this,       SW_RES(CB_KEY2  )),
150     aColEdt2(this,      SW_RES(ED_KEY2  )),
151     aTypDLB2(this,      SW_RES(DLB_KEY2 )),
152     aSortUp2RB(this,    SW_RES(RB_UP2    )),
153     aSortDn2RB(this,    SW_RES(RB_DN2    )),
154 
155     aKeyCB3(this,       SW_RES(CB_KEY3  )),
156     aColEdt3(this,      SW_RES(ED_KEY3  )),
157     aTypDLB3(this,      SW_RES(DLB_KEY3 )),
158     aSortUp3RB(this,    SW_RES(RB_UP3    )),
159     aSortDn3RB(this,    SW_RES(RB_DN3    )),
160     aDirFL(this,       SW_RES(FL_DIR   )),
161 
162     aColumnRB(this,     SW_RES(RB_COL   )),
163     aRowRB(this,        SW_RES(RB_ROW   )),
164 
165     aDelimFL(this,     SW_RES(FL_DELIM )),
166     aDelimTabRB(this,   SW_RES(RB_TAB   )),
167     aDelimFreeRB(this,  SW_RES(RB_TABCH )),
168     aDelimEdt(this,     SW_RES(ED_TABCH )),
169     aDelimPB(this,      SW_RES( PB_DELIM)),
170 
171     aLangFL(this,       SW_RES( FL_LANG )),
172     aLangLB(this,       SW_RES( LB_LANG )),
173 
174     aSortOptFL(this,    SW_RES( FL_SORT )),
175     aCaseCB(this,       SW_RES( CB_CASE )),
176 
177     aOkBtn(this,        SW_RES(BT_OK    )),
178     aCancelBtn(this,    SW_RES(BT_CANCEL)),
179     aHelpBtn(this,      SW_RES(BT_HELP  )),
180 
181     aColTxt(            SW_RES(STR_COL)),
182     aRowTxt(            SW_RES(STR_ROW)),
183     aNumericTxt(        SW_RES(STR_NUMERIC)),
184     rSh(rShell),
185     pColRes( 0 ),
186     nX( 99 ),
187     nY( 99 )
188 {
189     aColEdt1.SetAccessibleName(aColLbl.GetText());
190     aColEdt2.SetAccessibleName(aColLbl.GetText());
191     aColEdt3.SetAccessibleName(aColLbl.GetText());
192     aTypDLB1.SetAccessibleName(aTypLbl.GetText());
193     aTypDLB2.SetAccessibleName(aTypLbl.GetText());
194     aTypDLB3.SetAccessibleName(aTypLbl.GetText());
195     aSortUpRB.SetAccessibleRelationMemberOf( &aKeyCB1 );
196     aSortDnRB.SetAccessibleRelationMemberOf( &aKeyCB1 );
197     aSortUp2RB.SetAccessibleRelationMemberOf( &aKeyCB2 );
198     aSortDn2RB.SetAccessibleRelationMemberOf( &aKeyCB2 );
199     aSortUp3RB.SetAccessibleRelationMemberOf( &aKeyCB3 );
200     aSortDn3RB.SetAccessibleRelationMemberOf( &aKeyCB3 );
201 
202     aDelimEdt.SetMaxTextLen( 1 );
203     if(rSh.GetSelectionType() &
204             (nsSelectionType::SEL_TBL|nsSelectionType::SEL_TBL_CELLS) )
205     {
206         aColumnRB.Check(bCol);
207         aColLbl.SetText(bCol ? aRowTxt : aColTxt);
208         aRowRB.Check(!bCol);
209         aDelimTabRB.Enable(sal_False);
210         aDelimFreeRB.Enable(sal_False);
211         aDelimEdt.Enable(sal_False);
212     }
213     else
214     {
215         aColumnRB.Enable(sal_False);
216         aRowRB.Check(sal_True);
217         aColLbl.SetText(aColTxt);
218     }
219 
220     // Initialisieren
221     Link aLk = LINK(this,SwSortDlg, CheckHdl);
222     aKeyCB1.SetClickHdl( aLk );
223     aKeyCB2.SetClickHdl( aLk );
224     aKeyCB3.SetClickHdl( aLk );
225     aColumnRB.SetClickHdl( aLk );
226     aRowRB.SetClickHdl( aLk );
227 
228     aLk = LINK(this,SwSortDlg, DelimHdl);
229     aDelimFreeRB.SetClickHdl(aLk);
230     aDelimTabRB.SetClickHdl(aLk);
231 
232     aDelimPB.SetClickHdl( LINK( this, SwSortDlg, DelimCharHdl ));
233 
234     aKeyCB1.Check(bCheck1);
235     aKeyCB2.Check(bCheck2);
236     aKeyCB3.Check(bCheck3);
237 
238     aColEdt1.SetValue(nCol1);
239     aColEdt2.SetValue(nCol2);
240     aColEdt3.SetValue(nCol3);
241 
242     // first initialise the language, then select the
243     if( LANGUAGE_NONE == nLang || LANGUAGE_DONTKNOW == nLang )
244         nLang = (sal_uInt16)GetAppLanguage();
245 
246     aLangLB.SetLanguageList( LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, sal_True, sal_False);
247     aLangLB.SelectLanguage( nLang );
248 
249     LanguageHdl( 0 );
250     aLangLB.SetSelectHdl( LINK( this, SwSortDlg, LanguageHdl ));
251 
252     aSortUpRB.Check(bAsc1);
253     aSortDnRB.Check(!bAsc1);
254     aSortUp2RB.Check(bAsc2);
255     aSortDn2RB.Check(!bAsc2);
256     aSortUp3RB.Check(bAsc3);
257     aSortDn3RB.Check(!bAsc3);
258 
259     aCaseCB.Check( bCsSens );
260 
261     aDelimTabRB.Check(cDeli == '\t');
262     if(!aDelimTabRB.IsChecked())
263     {
264         aDelimEdt.SetText(cDeli);
265         aDelimFreeRB.Check(sal_True);
266         DelimHdl(&aDelimFreeRB);
267     }
268     else
269         DelimHdl(&aDelimTabRB);
270 
271     FreeResource();
272     if( ::lcl_GetSelTbl( rSh, nX, nY) )
273     {
274         sal_uInt16 nMax = aRowRB.IsChecked()? nY : nX;
275         aColEdt1.SetMax(nMax);
276         aColEdt2.SetMax(nMax);
277         aColEdt3.SetMax(nMax);
278     }
279 
280     aDelimEdt.SetAccessibleRelationLabeledBy(&aDelimFreeRB);
281     aDelimPB.SetAccessibleRelationLabeledBy(&aDelimFreeRB);
282     aDelimPB.SetAccessibleRelationMemberOf(&aDelimFL);
283 
284     aColEdt1.SetAccessibleRelationMemberOf(&aKeyCB1);
285     aColEdt1.SetAccessibleRelationLabeledBy(&aColLbl);
286     aTypDLB1.SetAccessibleRelationMemberOf(&aKeyCB1);
287     aTypDLB1.SetAccessibleRelationLabeledBy(&aTypLbl);
288 
289     aColEdt2.SetAccessibleRelationMemberOf(&aKeyCB2);
290     aColEdt2.SetAccessibleRelationLabeledBy(&aColLbl);
291     aTypDLB2.SetAccessibleRelationMemberOf(&aKeyCB2);
292     aTypDLB2.SetAccessibleRelationLabeledBy(&aTypLbl);
293 
294     aColEdt3.SetAccessibleRelationMemberOf(&aKeyCB3);
295     aColEdt3.SetAccessibleRelationLabeledBy(&aColLbl);
296     aTypDLB3.SetAccessibleRelationMemberOf(&aKeyCB3);
297     aTypDLB3.SetAccessibleRelationLabeledBy(&aTypLbl);
298 }
299 
300 SwSortDlg::~SwSortDlg()
301 {
302     ::lcl_ClearLstBoxAndDelUserData( aTypDLB1 );
303     ::lcl_ClearLstBoxAndDelUserData( aTypDLB2 );
304     ::lcl_ClearLstBoxAndDelUserData( aTypDLB3 );
305     delete pColRes;
306 }
307 
308 sal_Unicode SwSortDlg::GetDelimChar() const
309 {
310     sal_Unicode cRet = '\t';
311     if( !aDelimTabRB.IsChecked() )
312     {
313         String aTmp( aDelimEdt.GetText() );
314         if( aTmp.Len() )
315             cRet = aTmp.GetChar( 0 );
316     }
317     return cRet;
318 }
319 
320 /*--------------------------------------------------------------------
321     Beschreibung: An die Core weiterreichen
322  --------------------------------------------------------------------*/
323 void SwSortDlg::Apply()
324 {
325     // Alte Einstellung speichern
326     //
327     bCheck1 = aKeyCB1.IsChecked();
328     bCheck2 = aKeyCB2.IsChecked();
329     bCheck3 = aKeyCB3.IsChecked();
330 
331     nCol1 = (sal_uInt16)aColEdt1.GetValue();
332     nCol2 = (sal_uInt16)aColEdt2.GetValue();
333     nCol3 = (sal_uInt16)aColEdt3.GetValue();
334 
335     nType1 = aTypDLB1.GetSelectEntryPos();
336     nType2 = aTypDLB2.GetSelectEntryPos();
337     nType3 = aTypDLB3.GetSelectEntryPos();
338 
339     bAsc1 = aSortUpRB.IsChecked();
340     bAsc2 = aSortUp2RB.IsChecked();
341     bAsc3 = aSortUp3RB.IsChecked();
342     bCol = aColumnRB.IsChecked();
343     nLang = aLangLB.GetSelectLanguage();
344     cDeli = GetDelimChar();
345     bCsSens = aCaseCB.IsChecked();
346 
347     void* pUserData;
348     SwSortOptions aOptions;
349     if( bCheck1 )
350     {
351         String sEntry( aTypDLB1.GetSelectEntry() );
352         if( sEntry == aNumericTxt )
353             sEntry.Erase();
354         else if( 0 != (pUserData = aTypDLB1.GetEntryData(
355                                             aTypDLB1.GetSelectEntryPos())) )
356             sEntry = *(String*)pUserData;
357 
358         SwSortKey *pKey = new SwSortKey( nCol1, sEntry,
359                                     bAsc1 ? SRT_ASCENDING : SRT_DESCENDING );
360         aOptions.aKeys.C40_INSERT(SwSortKey, pKey, aOptions.aKeys.Count());
361     }
362 
363     if( bCheck2 )
364     {
365         String sEntry( aTypDLB2.GetSelectEntry() );
366         if( sEntry == aNumericTxt )
367             sEntry.Erase();
368         else if( 0 != (pUserData = aTypDLB2.GetEntryData(
369                                             aTypDLB2.GetSelectEntryPos())) )
370             sEntry = *(String*)pUserData;
371 
372         SwSortKey *pKey = new SwSortKey( nCol2, sEntry,
373                                     bAsc2 ? SRT_ASCENDING : SRT_DESCENDING );
374         aOptions.aKeys.C40_INSERT( SwSortKey, pKey, aOptions.aKeys.Count() );
375     }
376 
377     if( bCheck3 )
378     {
379         String sEntry( aTypDLB3.GetSelectEntry() );
380         if( sEntry == aNumericTxt )
381             sEntry.Erase();
382         else if( 0 != (pUserData = aTypDLB3.GetEntryData(
383                                             aTypDLB3.GetSelectEntryPos())) )
384             sEntry = *(String*)pUserData;
385 
386         SwSortKey *pKey = new SwSortKey( nCol3, sEntry,
387                                     bAsc3 ? SRT_ASCENDING : SRT_DESCENDING );
388         aOptions.aKeys.C40_INSERT( SwSortKey, pKey, aOptions.aKeys.Count() );
389     }
390 
391     aOptions.eDirection =  bCol ? SRT_COLUMNS : SRT_ROWS;
392     aOptions.cDeli = cDeli;
393     aOptions.nLanguage = nLang;
394     aOptions.bTable = rSh.IsTableMode();
395     aOptions.bIgnoreCase = !bCsSens;
396 
397     sal_Bool bRet;
398     {
399         SwWait aWait( *rSh.GetView().GetDocShell(), sal_True );
400         rSh.StartAllAction();
401         if( 0 != (bRet = rSh.Sort( aOptions )))
402             rSh.SetModified();
403         rSh.EndAllAction();
404     }
405 
406     if( !bRet )
407         InfoBox( this->GetParent(), SW_RES(MSG_SRTERR)).Execute();
408 }
409 
410 /* -----------------30.09.98 10:03-------------------
411  *
412  * --------------------------------------------------*/
413 IMPL_LINK( SwSortDlg, DelimHdl, RadioButton*, pButton )
414 {
415     sal_Bool bEnable = pButton == &aDelimFreeRB && aDelimFreeRB.IsEnabled();
416     aDelimEdt.Enable( bEnable );
417     aDelimPB.Enable( bEnable );
418     return 0;
419 }
420 
421 IMPL_LINK( SwSortDlg, DelimCharHdl, PushButton*, EMPTYARG )
422 {
423     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
424     if(pFact)
425     {
426         SfxAllItemSet aSet( rSh.GetAttrPool() );
427         aSet.Put( SfxInt32Item( SID_ATTR_CHAR, GetDelimChar() ) );
428         SfxAbstractDialog* pMap = pFact->CreateSfxDialog( &aDelimPB, aSet,
429             rSh.GetView().GetViewFrame()->GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP );
430         if( RET_OK == pMap->Execute() )
431         {
432             SFX_ITEMSET_ARG( pMap->GetOutputItemSet(), pItem, SfxInt32Item, SID_ATTR_CHAR, sal_False );
433             if ( pItem )
434                 aDelimEdt.SetText( sal_Unicode ( pItem->GetValue() ) );
435         }
436 
437         delete pMap;
438     }
439     return 0;
440 }
441 
442 
443 IMPL_LINK( SwSortDlg, CheckHdl, CheckBox *, pCheck )
444 {
445     if( pCheck == ( CheckBox* ) &aRowRB)
446     {
447         aColLbl.SetText(aColTxt);
448         aColEdt1.SetMax(nY);
449         aColEdt2.SetMax(nY);
450         aColEdt3.SetMax(nY);
451 
452         aColEdt1.SetAccessibleName(aColTxt);
453         aColEdt2.SetAccessibleName(aColTxt);
454         aColEdt3.SetAccessibleName(aColTxt);
455     }
456     else if( pCheck == ( CheckBox* ) &aColumnRB)
457     {
458         aColLbl.SetText(aRowTxt);
459         aColEdt1.SetMax(nX);
460         aColEdt2.SetMax(nX);
461         aColEdt3.SetMax(nX);
462 
463         aColEdt1.SetAccessibleName(aRowTxt);
464         aColEdt2.SetAccessibleName(aRowTxt);
465         aColEdt3.SetAccessibleName(aRowTxt);
466     }
467     else if(!aKeyCB1.IsChecked() &&
468                 !aKeyCB2.IsChecked() &&
469                     !aKeyCB3.IsChecked())
470         pCheck->Check(sal_True);
471     return 0;
472 }
473 
474 IMPL_LINK( SwSortDlg, LanguageHdl, ListBox*, pLBox )
475 {
476     Locale aLcl( SvxCreateLocale( aLangLB.GetSelectLanguage() ) );
477     Sequence < OUString > aSeq(
478                             GetAppCollator().listCollatorAlgorithms( aLcl ));
479 
480     if( !pColRes )
481         pColRes = new CollatorRessource();
482 
483     const sal_uInt16 nLstBoxCnt = 3;
484     ListBox* aLstArr[ nLstBoxCnt ] = { &aTypDLB1, &aTypDLB2, &aTypDLB3 };
485     sal_uInt16* aTypeArr[ nLstBoxCnt ] = { &nType1, &nType2, &nType3 };
486     String aOldStrArr[ nLstBoxCnt ];
487     sal_uInt16 n;
488 
489     void* pUserData;
490     for( n = 0; n < nLstBoxCnt; ++n )
491     {
492         ListBox* pL = aLstArr[ n ];
493         if( 0 != (pUserData = pL->GetEntryData( pL->GetSelectEntryPos())) )
494             aOldStrArr[ n ] = *(String*)pUserData;
495         ::lcl_ClearLstBoxAndDelUserData( *pL );
496     }
497 
498     sal_uInt16 nInsPos;
499     String sAlg, sUINm;
500     for( long nCnt = 0, nEnd = aSeq.getLength(); nCnt <= nEnd; ++nCnt )
501     {
502         if( nCnt < nEnd )
503             sUINm = pColRes->GetTranslation( sAlg = aSeq[ nCnt ] );
504         else
505             sUINm = sAlg = aNumericTxt;
506 
507         for( n = 0; n < nLstBoxCnt; ++n )
508         {
509             ListBox* pL = aLstArr[ n ];
510             nInsPos = pL->InsertEntry( sUINm );
511             pL->SetEntryData( nInsPos, new String( sAlg ));
512             if( pLBox && sAlg == aOldStrArr[ n ] )
513                 pL->SelectEntryPos( nInsPos );
514         }
515     }
516 
517     for( n = 0; n < nLstBoxCnt; ++n )
518     {
519         ListBox* pL = aLstArr[ n ];
520         if( !pLBox )
521             pL->SelectEntryPos( *aTypeArr[n] );
522         else if( LISTBOX_ENTRY_NOTFOUND == pL->GetSelectEntryPos() )
523             pL->SelectEntryPos( 0 );
524     }
525     return 0;
526 }
527 
528 
529 
530 
531 
532 
533