xref: /aoo42x/main/sc/source/ui/dbgui/tpsort.cxx (revision cdf0e10c)
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