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