1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #undef SC_DLLIMPLEMENTATION
22 #include "scitems.hxx"
23 #include "uiitems.hxx"
25 #include "userlist.hxx"
26 #include "viewdata.hxx"
27 #include "document.hxx"
28 #include "scresid.hxx"
31 #include "subtdlg.hxx"
33 #include <boost/scoped_array.hpp>
35 // Subtotals group tabpage:
37 ScTpSubTotalGroup::ScTpSubTotalGroup( Window
* pParent
,
38 const SfxItemSet
& rArgSet
)
39 : SfxTabPage ( pParent
,
40 "SubTotalGrpPage", "modules/scalc/ui/subtotalgrppage.ui",
42 aStrNone ( SC_RESSTR( SCSTR_NONE
) ),
43 aStrColumn ( SC_RESSTR( SCSTR_COLUMN
) ),
46 nWhichSubTotals ( rArgSet
.GetPool()->GetWhich( SID_SUBTOTALS
) ),
47 rSubTotalData ( ((const ScSubTotalItem
&)
48 rArgSet
.Get( nWhichSubTotals
)).
52 get(mpLbGroup
, "group_by");
53 get(mpLbColumns
, "columns");
54 get(mpLbFunctions
, "functions");
56 long nHeight
= mpLbColumns
->GetTextHeight() * 14;
57 mpLbColumns
->set_height_request(nHeight
);
58 mpLbFunctions
->set_height_request(nHeight
);
60 // Font is correctly initialized by SvTreeListBox ctor
61 mpLbColumns
->SetSelectionMode( SINGLE_SELECTION
);
62 mpLbColumns
->SetDragDropMode( SV_DRAGDROP_NONE
);
63 mpLbColumns
->SetSpaceBetweenEntries( 0 );
68 ScTpSubTotalGroup::~ScTpSubTotalGroup()
70 sal_uLong nCount
= mpLbColumns
->GetEntryCount();
74 sal_uInt16
* pData
= NULL
;
76 for ( sal_uLong i
=0; i
<nCount
; i
++ )
78 pData
= (sal_uInt16
*)(mpLbColumns
->GetEntryData( i
));
79 OSL_ENSURE( pData
, "EntryData not found" );
86 void ScTpSubTotalGroup::Init()
88 const ScSubTotalItem
& rSubTotalItem
= (const ScSubTotalItem
&)
89 GetItemSet().Get( nWhichSubTotals
);
91 pViewData
= rSubTotalItem
.GetViewData();
92 pDoc
= ( pViewData
) ? pViewData
->GetDocument() : NULL
;
94 OSL_ENSURE( pViewData
&& pDoc
, "ViewData or Document not found :-(" );
96 mpLbGroup
->SetSelectHdl ( LINK( this, ScTpSubTotalGroup
, SelectHdl
) );
97 mpLbColumns
->SetSelectHdl ( LINK( this, ScTpSubTotalGroup
, SelectHdl
) );
98 mpLbColumns
->SetCheckButtonHdl ( LINK( this, ScTpSubTotalGroup
, CheckHdl
) );
99 mpLbFunctions
->SetSelectHdl ( LINK( this, ScTpSubTotalGroup
, SelectHdl
) );
105 bool ScTpSubTotalGroup::DoReset( sal_uInt16 nGroupNo
,
106 const SfxItemSet
& rArgSet
)
108 sal_uInt16 nGroupIdx
= 0;
110 OSL_ENSURE( (nGroupNo
<=3) && (nGroupNo
>0), "Invalid group" );
112 if ( (nGroupNo
> 3) || (nGroupNo
== 0) )
115 nGroupIdx
= nGroupNo
-1;
117 // first we have to clear the listboxes...
118 for ( sal_uLong nLbEntry
= 0; nLbEntry
< mpLbColumns
->GetEntryCount(); ++nLbEntry
)
120 mpLbColumns
->CheckEntryPos( nLbEntry
, false );
121 *((sal_uInt16
*)mpLbColumns
->GetEntryData( nLbEntry
)) = 0;
123 mpLbFunctions
->SelectEntryPos( 0 );
125 ScSubTotalParam
theSubTotalData( ((const ScSubTotalItem
&)
126 rArgSet
.Get( nWhichSubTotals
)).
129 if ( theSubTotalData
.bGroupActive
[nGroupIdx
] )
131 SCCOL nField
= theSubTotalData
.nField
[nGroupIdx
];
132 SCCOL nSubTotals
= theSubTotalData
.nSubTotals
[nGroupIdx
];
133 SCCOL
* pSubTotals
= theSubTotalData
.pSubTotals
[nGroupIdx
];
134 ScSubTotalFunc
* pFunctions
= theSubTotalData
.pFunctions
[nGroupIdx
];
136 mpLbGroup
->SelectEntryPos( GetFieldSelPos( nField
)+1 );
138 sal_uInt16 nFirstChecked
= 0;
139 for ( sal_uInt16 i
=0; i
<nSubTotals
; i
++ )
141 sal_uInt16 nCheckPos
= GetFieldSelPos( pSubTotals
[i
] );
142 sal_uInt16
* pFunction
= (sal_uInt16
*)mpLbColumns
->GetEntryData( nCheckPos
);
144 mpLbColumns
->CheckEntryPos( nCheckPos
);
145 *pFunction
= FuncToLbPos( pFunctions
[i
] );
147 if (i
== 0 || (i
> 0 && nCheckPos
< nFirstChecked
))
148 nFirstChecked
= nCheckPos
;
150 // Select the first checked field from the top.
151 mpLbColumns
->SelectEntryPos(nFirstChecked
);
155 mpLbGroup
->SelectEntryPos( (nGroupNo
== 1) ? 1 : 0 );
156 mpLbColumns
->SelectEntryPos( 0 );
157 mpLbFunctions
->SelectEntryPos( 0 );
163 bool ScTpSubTotalGroup::DoFillItemSet( sal_uInt16 nGroupNo
,
164 SfxItemSet
& rArgSet
)
166 sal_uInt16 nGroupIdx
= 0;
168 OSL_ENSURE( (nGroupNo
<=3) && (nGroupNo
>0), "Invalid group" );
169 OSL_ENSURE( (mpLbGroup
->GetEntryCount() > 0)
170 && (mpLbColumns
->GetEntryCount() > 0)
171 && (mpLbFunctions
->GetEntryCount() > 0),
172 "Non-initialized Lists" );
175 if ( (nGroupNo
> 3) || (nGroupNo
== 0)
176 || (mpLbGroup
->GetEntryCount() == 0)
177 || (mpLbColumns
->GetEntryCount() == 0)
178 || (mpLbFunctions
->GetEntryCount() == 0)
182 nGroupIdx
= nGroupNo
-1;
184 ScSubTotalParam theSubTotalData
; // auslesen, wenn schon teilweise gefuellt
185 SfxTabDialog
* pDlg
= GetTabDialog();
188 const SfxItemSet
* pExample
= pDlg
->GetExampleSet();
189 const SfxPoolItem
* pItem
;
190 if ( pExample
&& pExample
->GetItemState( nWhichSubTotals
, true, &pItem
) == SFX_ITEM_SET
)
191 theSubTotalData
= ((const ScSubTotalItem
*)pItem
)->GetSubTotalData();
194 boost::scoped_array
<ScSubTotalFunc
> pFunctions
;
195 boost::scoped_array
<SCCOL
> pSubTotals
;
196 sal_uInt16 nGroup
= mpLbGroup
->GetSelectEntryPos();
197 sal_uInt16 nEntryCount
= (sal_uInt16
)mpLbColumns
->GetEntryCount();
198 sal_uInt16 nCheckCount
= mpLbColumns
->GetCheckedEntryCount();
200 theSubTotalData
.nCol1
= rSubTotalData
.nCol1
;
201 theSubTotalData
.nRow1
= rSubTotalData
.nRow1
;
202 theSubTotalData
.nCol2
= rSubTotalData
.nCol2
;
203 theSubTotalData
.nRow2
= rSubTotalData
.nRow2
;
204 theSubTotalData
.bGroupActive
[nGroupIdx
] = (nGroup
!= 0);
205 theSubTotalData
.nField
[nGroupIdx
] = (nGroup
!= 0)
206 ? nFieldArr
[nGroup
-1]
207 : static_cast<SCCOL
>(0);
209 if ( nEntryCount
>0 && nCheckCount
>0 && nGroup
!=0 )
211 sal_uInt16 nFunction
= 0;
213 pSubTotals
.reset(new SCCOL
[nCheckCount
]);
214 pFunctions
.reset(new ScSubTotalFunc
[nCheckCount
]);
216 for ( sal_uInt16 i
=0, nCheck
=0; i
<nEntryCount
; i
++ )
218 if ( mpLbColumns
->IsChecked( i
) )
220 OSL_ENSURE( nCheck
<= nCheckCount
,
222 nFunction
= *((sal_uInt16
*)mpLbColumns
->GetEntryData( i
));
223 pSubTotals
[nCheck
] = nFieldArr
[i
];
224 pFunctions
[nCheck
] = LbPosToFunc( nFunction
);
228 theSubTotalData
.SetSubTotals( nGroupNo
, // Gruppen-Nr.
231 nCheckCount
); // Anzahl der Array-Elemente
235 rArgSet
.Put( ScSubTotalItem( SCITEM_SUBTDATA
, &theSubTotalData
) );
240 void ScTpSubTotalGroup::FillListBoxes()
242 OSL_ENSURE( pViewData
&& pDoc
, "ViewData or Document not found :-/" );
244 if ( pViewData
&& pDoc
)
246 SCCOL nFirstCol
= rSubTotalData
.nCol1
;
247 SCROW nFirstRow
= rSubTotalData
.nRow1
;
248 SCTAB nTab
= pViewData
->GetTabNo();
249 SCCOL nMaxCol
= rSubTotalData
.nCol2
;
254 mpLbColumns
->Clear();
255 mpLbGroup
->InsertEntry( aStrNone
, 0 );
258 for ( col
=nFirstCol
; col
<=nMaxCol
&& i
<SC_MAXFIELDS
; col
++ )
260 aFieldName
= pDoc
->GetString(col
, nFirstRow
, nTab
);
261 if ( aFieldName
.isEmpty() )
263 aFieldName
= ScGlobal::ReplaceOrAppend( aStrColumn
, "%1", ScColToAlpha( col
));
266 mpLbGroup
->InsertEntry( aFieldName
, i
+1 );
267 mpLbColumns
->InsertEntry( aFieldName
, i
);
268 mpLbColumns
->SetEntryData( i
, new sal_uInt16(0) );
271 // subsequent initialization of the constant:
272 (sal_uInt16
&)nFieldCount
= i
;
276 sal_uInt16
ScTpSubTotalGroup::GetFieldSelPos( SCCOL nField
)
278 sal_uInt16 nFieldPos
= 0;
281 for ( sal_uInt16 n
=0; n
<nFieldCount
&& !bFound
; n
++ )
283 if ( nFieldArr
[n
] == nField
)
293 ScSubTotalFunc
ScTpSubTotalGroup::LbPosToFunc( sal_uInt16 nPos
)
297 // case 0: return SUBTOTAL_FUNC_NONE;
298 case 2: return SUBTOTAL_FUNC_AVE
;
299 case 6: return SUBTOTAL_FUNC_CNT
;
300 case 1: return SUBTOTAL_FUNC_CNT2
;
301 case 3: return SUBTOTAL_FUNC_MAX
;
302 case 4: return SUBTOTAL_FUNC_MIN
;
303 case 5: return SUBTOTAL_FUNC_PROD
;
304 case 7: return SUBTOTAL_FUNC_STD
;
305 case 8: return SUBTOTAL_FUNC_STDP
;
306 case 0: return SUBTOTAL_FUNC_SUM
;
307 case 9: return SUBTOTAL_FUNC_VAR
;
308 case 10: return SUBTOTAL_FUNC_VARP
;
310 OSL_FAIL( "ScTpSubTotalGroup::LbPosToFunc" );
311 return SUBTOTAL_FUNC_NONE
;
315 sal_uInt16
ScTpSubTotalGroup::FuncToLbPos( ScSubTotalFunc eFunc
)
319 // case SUBTOTAL_FUNC_NONE: return 0;
320 case SUBTOTAL_FUNC_AVE
: return 2;
321 case SUBTOTAL_FUNC_CNT
: return 6;
322 case SUBTOTAL_FUNC_CNT2
: return 1;
323 case SUBTOTAL_FUNC_MAX
: return 3;
324 case SUBTOTAL_FUNC_MIN
: return 4;
325 case SUBTOTAL_FUNC_PROD
: return 5;
326 case SUBTOTAL_FUNC_STD
: return 7;
327 case SUBTOTAL_FUNC_STDP
: return 8;
328 case SUBTOTAL_FUNC_SUM
: return 0;
329 case SUBTOTAL_FUNC_VAR
: return 9;
330 case SUBTOTAL_FUNC_VARP
: return 10;
332 OSL_FAIL( "ScTpSubTotalGroup::FuncToLbPos" );
341 IMPL_LINK( ScTpSubTotalGroup
, SelectHdl
, ListBox
*, pLb
)
343 if ( (mpLbColumns
->GetEntryCount() > 0)
344 && (mpLbColumns
->GetSelectionCount() > 0) )
346 sal_uInt16 nFunction
= mpLbFunctions
->GetSelectEntryPos();
347 sal_uInt16 nColumn
= mpLbColumns
->GetSelectEntryPos();
348 sal_uInt16
* pFunction
= (sal_uInt16
*)mpLbColumns
->GetEntryData( nColumn
);
350 OSL_ENSURE( pFunction
, "EntryData not found!" );
354 if ( ((SvxCheckListBox
*)pLb
) == mpLbColumns
)
356 mpLbFunctions
->SelectEntryPos( *pFunction
);
358 else if ( pLb
== mpLbFunctions
)
360 *pFunction
= nFunction
;
361 mpLbColumns
->CheckEntryPos( nColumn
, true );
367 IMPL_LINK( ScTpSubTotalGroup
, CheckHdl
, ListBox
*, pLb
)
369 if ( ((SvxCheckListBox
*)pLb
) == mpLbColumns
)
371 SvTreeListEntry
* pEntry
= mpLbColumns
->GetHdlEntry();
375 mpLbColumns
->SelectEntryPos( (sal_uInt16
)mpLbColumns
->GetModel()->GetAbsPos( pEntry
) );
383 // Derived Group TabPages:
385 SfxTabPage
* ScTpSubTotalGroup1::Create( Window
* pParent
,
386 const SfxItemSet
& rArgSet
)
387 { return ( new ScTpSubTotalGroup1( pParent
, rArgSet
) ); }
389 SfxTabPage
* ScTpSubTotalGroup2::Create( Window
* pParent
,
390 const SfxItemSet
& rArgSet
)
391 { return ( new ScTpSubTotalGroup2( pParent
, rArgSet
) ); }
393 SfxTabPage
* ScTpSubTotalGroup3::Create( Window
* pParent
,
394 const SfxItemSet
& rArgSet
)
395 { return ( new ScTpSubTotalGroup3( pParent
, rArgSet
) ); }
397 ScTpSubTotalGroup1::ScTpSubTotalGroup1( Window
* pParent
, const SfxItemSet
& rArgSet
) :
398 ScTpSubTotalGroup( pParent
, rArgSet
)
401 ScTpSubTotalGroup2::ScTpSubTotalGroup2( Window
* pParent
, const SfxItemSet
& rArgSet
) :
402 ScTpSubTotalGroup( pParent
, rArgSet
)
405 ScTpSubTotalGroup3::ScTpSubTotalGroup3( Window
* pParent
, const SfxItemSet
& rArgSet
) :
406 ScTpSubTotalGroup( pParent
, rArgSet
)
410 #define RESET(i) (ScTpSubTotalGroup::DoReset( (i), rArgSet ))
411 void ScTpSubTotalGroup1::Reset( const SfxItemSet
& rArgSet
) { RESET(1); }
412 void ScTpSubTotalGroup2::Reset( const SfxItemSet
& rArgSet
) { RESET(2); }
413 void ScTpSubTotalGroup3::Reset( const SfxItemSet
& rArgSet
) { RESET(3); }
416 #define FILLSET(i) (ScTpSubTotalGroup::DoFillItemSet( (i), rArgSet ))
417 bool ScTpSubTotalGroup1::FillItemSet( SfxItemSet
& rArgSet
) { return FILLSET(1); }
418 bool ScTpSubTotalGroup2::FillItemSet( SfxItemSet
& rArgSet
) { return FILLSET(2); }
419 bool ScTpSubTotalGroup3::FillItemSet( SfxItemSet
& rArgSet
) { return FILLSET(3); }
425 ScTpSubTotalOptions::ScTpSubTotalOptions( Window
* pParent
,
426 const SfxItemSet
& rArgSet
)
428 : SfxTabPage ( pParent
,
429 "SubTotalOptionsPage", "modules/scalc/ui/subtotaloptionspage.ui" ,
433 nWhichSubTotals ( rArgSet
.GetPool()->GetWhich( SID_SUBTOTALS
) ),
434 rSubTotalData ( ((const ScSubTotalItem
&)
435 rArgSet
.Get( nWhichSubTotals
)).
438 get(pBtnPagebreak
,"pagebreak");
439 get(pBtnCase
,"case");
440 get(pBtnSort
,"sort");
441 get(pFlSort
,"label2");
442 get(pBtnAscending
,"ascending");
443 get(pBtnDescending
,"descending");
444 get(pBtnFormats
,"formats");
445 get(pBtnUserDef
,"btnuserdef");
446 get(pLbUserDef
,"lbuserdef");
451 ScTpSubTotalOptions::~ScTpSubTotalOptions()
455 void ScTpSubTotalOptions::Init()
457 const ScSubTotalItem
& rSubTotalItem
= (const ScSubTotalItem
&)
458 GetItemSet().Get( nWhichSubTotals
);
460 pViewData
= rSubTotalItem
.GetViewData();
461 pDoc
= ( pViewData
) ? pViewData
->GetDocument() : NULL
;
463 OSL_ENSURE( pViewData
&& pDoc
, "ViewData or Document not found!" );
465 pBtnSort
->SetClickHdl ( LINK( this, ScTpSubTotalOptions
, CheckHdl
) );
466 pBtnUserDef
->SetClickHdl ( LINK( this, ScTpSubTotalOptions
, CheckHdl
) );
468 FillUserSortListBox();
471 SfxTabPage
* ScTpSubTotalOptions::Create( Window
* pParent
,
472 const SfxItemSet
& rArgSet
)
474 return ( new ScTpSubTotalOptions( pParent
, rArgSet
) );
477 void ScTpSubTotalOptions::Reset( const SfxItemSet
& /* rArgSet */ )
479 pBtnPagebreak
->Check ( rSubTotalData
.bPagebreak
);
480 pBtnCase
->Check ( rSubTotalData
.bCaseSens
);
481 pBtnFormats
->Check ( rSubTotalData
.bIncludePattern
);
482 pBtnSort
->Check ( rSubTotalData
.bDoSort
);
483 pBtnAscending
->Check ( rSubTotalData
.bAscending
);
484 pBtnDescending
->Check( !rSubTotalData
.bAscending
);
486 if ( rSubTotalData
.bUserDef
)
488 pBtnUserDef
->Check( true );
489 pLbUserDef
->Enable();
490 pLbUserDef
->SelectEntryPos( rSubTotalData
.nUserIndex
);
494 pBtnUserDef
->Check( false );
495 pLbUserDef
->Disable();
496 pLbUserDef
->SelectEntryPos( 0 );
499 CheckHdl( pBtnSort
);
502 bool ScTpSubTotalOptions::FillItemSet( SfxItemSet
& rArgSet
)
504 ScSubTotalParam theSubTotalData
; // auslesen, wenn schon teilweise gefuellt
505 SfxTabDialog
* pDlg
= GetTabDialog();
508 const SfxItemSet
* pExample
= pDlg
->GetExampleSet();
509 const SfxPoolItem
* pItem
;
510 if ( pExample
&& pExample
->GetItemState( nWhichSubTotals
, true, &pItem
) == SFX_ITEM_SET
)
511 theSubTotalData
= ((const ScSubTotalItem
*)pItem
)->GetSubTotalData();
514 theSubTotalData
.bPagebreak
= pBtnPagebreak
->IsChecked();
515 theSubTotalData
.bReplace
= true;
516 theSubTotalData
.bCaseSens
= pBtnCase
->IsChecked();
517 theSubTotalData
.bIncludePattern
= pBtnFormats
->IsChecked();
518 theSubTotalData
.bDoSort
= pBtnSort
->IsChecked();
519 theSubTotalData
.bAscending
= pBtnAscending
->IsChecked();
520 theSubTotalData
.bUserDef
= pBtnUserDef
->IsChecked();
521 theSubTotalData
.nUserIndex
= (pBtnUserDef
->IsChecked())
522 ? pLbUserDef
->GetSelectEntryPos()
525 rArgSet
.Put( ScSubTotalItem( nWhichSubTotals
, &theSubTotalData
) );
530 void ScTpSubTotalOptions::FillUserSortListBox()
532 ScUserList
* pUserLists
= ScGlobal::GetUserList();
537 size_t nCount
= pUserLists
->size();
538 for ( size_t i
=0; i
<nCount
; ++i
)
539 pLbUserDef
->InsertEntry( (*pUserLists
)[i
]->GetString() );
546 IMPL_LINK( ScTpSubTotalOptions
, CheckHdl
, CheckBox
*, pBox
)
548 if ( pBox
== pBtnSort
)
550 if ( pBtnSort
->IsChecked() )
553 pBtnFormats
->Enable();
554 pBtnUserDef
->Enable();
555 pBtnAscending
->Enable();
556 pBtnDescending
->Enable();
558 if ( pBtnUserDef
->IsChecked() )
559 pLbUserDef
->Enable();
564 pBtnFormats
->Disable();
565 pBtnUserDef
->Disable();
566 pBtnAscending
->Disable();
567 pBtnDescending
->Disable();
568 pLbUserDef
->Disable();
571 else if ( pBox
== pBtnUserDef
)
573 if ( pBtnUserDef
->IsChecked() )
575 pLbUserDef
->Enable();
576 pLbUserDef
->GrabFocus();
579 pLbUserDef
->Disable();
585 ScTpSubTotalGroup1::~ScTpSubTotalGroup1()
589 ScTpSubTotalGroup2::~ScTpSubTotalGroup2()
593 ScTpSubTotalGroup3::~ScTpSubTotalGroup3()
597 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */