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