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