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( vcl::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 ( static_cast<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( DragDropMode::NONE
);
63 mpLbColumns
->SetSpaceBetweenEntries( 0 );
68 ScTpSubTotalGroup::~ScTpSubTotalGroup()
73 void ScTpSubTotalGroup::dispose()
75 sal_uLong nCount
= mpLbColumns
->GetEntryCount();
79 for ( sal_uLong i
=0; i
<nCount
; i
++ )
81 sal_uInt16
* pData
= static_cast<sal_uInt16
*>(mpLbColumns
->GetEntryData( i
));
82 OSL_ENSURE( pData
, "EntryData not found" );
89 mpLbFunctions
.clear();
90 SfxTabPage::dispose();
93 void ScTpSubTotalGroup::Init()
95 const ScSubTotalItem
& rSubTotalItem
= static_cast<const ScSubTotalItem
&>(
96 GetItemSet().Get( nWhichSubTotals
));
98 pViewData
= rSubTotalItem
.GetViewData();
99 pDoc
= ( pViewData
) ? pViewData
->GetDocument() : NULL
;
101 OSL_ENSURE( pViewData
&& pDoc
, "ViewData or Document not found :-(" );
103 mpLbGroup
->SetSelectHdl ( LINK( this, ScTpSubTotalGroup
, SelectHdl
) );
104 mpLbColumns
->SetSelectHdl ( LINK( this, ScTpSubTotalGroup
, SelectHdl
) );
105 mpLbColumns
->SetCheckButtonHdl ( LINK( this, ScTpSubTotalGroup
, CheckHdl
) );
106 mpLbFunctions
->SetSelectHdl ( LINK( this, ScTpSubTotalGroup
, SelectHdl
) );
112 bool ScTpSubTotalGroup::DoReset( sal_uInt16 nGroupNo
,
113 const SfxItemSet
& rArgSet
)
115 sal_uInt16 nGroupIdx
= 0;
117 OSL_ENSURE( (nGroupNo
<=3) && (nGroupNo
>0), "Invalid group" );
119 if ( (nGroupNo
> 3) || (nGroupNo
== 0) )
122 nGroupIdx
= nGroupNo
-1;
124 // first we have to clear the listboxes...
125 for ( sal_uLong nLbEntry
= 0; nLbEntry
< mpLbColumns
->GetEntryCount(); ++nLbEntry
)
127 mpLbColumns
->CheckEntryPos( nLbEntry
, false );
128 *static_cast<sal_uInt16
*>(mpLbColumns
->GetEntryData( nLbEntry
)) = 0;
130 mpLbFunctions
->SelectEntryPos( 0 );
132 ScSubTotalParam
theSubTotalData( static_cast<const ScSubTotalItem
&>(
133 rArgSet
.Get( nWhichSubTotals
)).
136 if ( theSubTotalData
.bGroupActive
[nGroupIdx
] )
138 SCCOL nField
= theSubTotalData
.nField
[nGroupIdx
];
139 SCCOL nSubTotals
= theSubTotalData
.nSubTotals
[nGroupIdx
];
140 SCCOL
* pSubTotals
= theSubTotalData
.pSubTotals
[nGroupIdx
];
141 ScSubTotalFunc
* pFunctions
= theSubTotalData
.pFunctions
[nGroupIdx
];
143 mpLbGroup
->SelectEntryPos( GetFieldSelPos( nField
)+1 );
145 sal_uInt16 nFirstChecked
= 0;
146 for ( sal_uInt16 i
=0; i
<nSubTotals
; i
++ )
148 sal_uInt16 nCheckPos
= GetFieldSelPos( pSubTotals
[i
] );
149 sal_uInt16
* pFunction
= static_cast<sal_uInt16
*>(mpLbColumns
->GetEntryData( nCheckPos
));
151 mpLbColumns
->CheckEntryPos( nCheckPos
);
152 *pFunction
= FuncToLbPos( pFunctions
[i
] );
154 if (i
== 0 || (i
> 0 && nCheckPos
< nFirstChecked
))
155 nFirstChecked
= nCheckPos
;
157 // Select the first checked field from the top.
158 mpLbColumns
->SelectEntryPos(nFirstChecked
);
162 mpLbGroup
->SelectEntryPos( (nGroupNo
== 1) ? 1 : 0 );
163 mpLbColumns
->SelectEntryPos( 0 );
164 mpLbFunctions
->SelectEntryPos( 0 );
170 bool ScTpSubTotalGroup::DoFillItemSet( sal_uInt16 nGroupNo
,
171 SfxItemSet
& rArgSet
)
173 sal_uInt16 nGroupIdx
= 0;
175 OSL_ENSURE( (nGroupNo
<=3) && (nGroupNo
>0), "Invalid group" );
176 OSL_ENSURE( (mpLbGroup
->GetEntryCount() > 0)
177 && (mpLbColumns
->GetEntryCount() > 0)
178 && (mpLbFunctions
->GetEntryCount() > 0),
179 "Non-initialized Lists" );
181 if ( (nGroupNo
> 3) || (nGroupNo
== 0)
182 || (mpLbGroup
->GetEntryCount() == 0)
183 || (mpLbColumns
->GetEntryCount() == 0)
184 || (mpLbFunctions
->GetEntryCount() == 0)
188 nGroupIdx
= nGroupNo
-1;
190 ScSubTotalParam theSubTotalData
; // auslesen, wenn schon teilweise gefuellt
191 SfxTabDialog
* pDlg
= GetTabDialog();
194 const SfxItemSet
* pExample
= pDlg
->GetExampleSet();
195 const SfxPoolItem
* pItem
;
196 if ( pExample
&& pExample
->GetItemState( nWhichSubTotals
, true, &pItem
) == SfxItemState::SET
)
197 theSubTotalData
= static_cast<const ScSubTotalItem
*>(pItem
)->GetSubTotalData();
200 boost::scoped_array
<ScSubTotalFunc
> pFunctions
;
201 boost::scoped_array
<SCCOL
> pSubTotals
;
202 sal_uInt16 nGroup
= mpLbGroup
->GetSelectEntryPos();
203 sal_uInt16 nEntryCount
= (sal_uInt16
)mpLbColumns
->GetEntryCount();
204 sal_uInt16 nCheckCount
= mpLbColumns
->GetCheckedEntryCount();
206 theSubTotalData
.nCol1
= rSubTotalData
.nCol1
;
207 theSubTotalData
.nRow1
= rSubTotalData
.nRow1
;
208 theSubTotalData
.nCol2
= rSubTotalData
.nCol2
;
209 theSubTotalData
.nRow2
= rSubTotalData
.nRow2
;
210 theSubTotalData
.bGroupActive
[nGroupIdx
] = (nGroup
!= 0);
211 theSubTotalData
.nField
[nGroupIdx
] = (nGroup
!= 0)
212 ? nFieldArr
[nGroup
-1]
213 : static_cast<SCCOL
>(0);
215 if ( nEntryCount
>0 && nCheckCount
>0 && nGroup
!=0 )
217 sal_uInt16 nFunction
= 0;
219 pSubTotals
.reset(new SCCOL
[nCheckCount
]);
220 pFunctions
.reset(new ScSubTotalFunc
[nCheckCount
]);
222 for ( sal_uInt16 i
=0, nCheck
=0; i
<nEntryCount
; i
++ )
224 if ( mpLbColumns
->IsChecked( i
) )
226 OSL_ENSURE( nCheck
<= nCheckCount
,
228 nFunction
= *static_cast<sal_uInt16
*>(mpLbColumns
->GetEntryData( i
));
229 pSubTotals
[nCheck
] = nFieldArr
[i
];
230 pFunctions
[nCheck
] = LbPosToFunc( nFunction
);
234 theSubTotalData
.SetSubTotals( nGroupNo
, // Gruppen-Nr.
237 nCheckCount
); // Anzahl der Array-Elemente
241 rArgSet
.Put( ScSubTotalItem( SCITEM_SUBTDATA
, &theSubTotalData
) );
246 void ScTpSubTotalGroup::FillListBoxes()
248 OSL_ENSURE( pViewData
&& pDoc
, "ViewData or Document not found :-/" );
250 if ( pViewData
&& pDoc
)
252 SCCOL nFirstCol
= rSubTotalData
.nCol1
;
253 SCROW nFirstRow
= rSubTotalData
.nRow1
;
254 SCTAB nTab
= pViewData
->GetTabNo();
255 SCCOL nMaxCol
= rSubTotalData
.nCol2
;
260 mpLbColumns
->Clear();
261 mpLbGroup
->InsertEntry( aStrNone
, 0 );
264 for ( col
=nFirstCol
; col
<=nMaxCol
&& i
<SC_MAXFIELDS
; col
++ )
266 aFieldName
= pDoc
->GetString(col
, nFirstRow
, nTab
);
267 if ( aFieldName
.isEmpty() )
269 aFieldName
= ScGlobal::ReplaceOrAppend( aStrColumn
, "%1", ScColToAlpha( col
));
272 mpLbGroup
->InsertEntry( aFieldName
, i
+1 );
273 mpLbColumns
->InsertEntry( aFieldName
, i
);
274 mpLbColumns
->SetEntryData( i
, new sal_uInt16(0) );
277 // subsequent initialization of the constant:
278 (sal_uInt16
&)nFieldCount
= i
;
282 sal_uInt16
ScTpSubTotalGroup::GetFieldSelPos( SCCOL nField
)
284 sal_uInt16 nFieldPos
= 0;
287 for ( sal_uInt16 n
=0; n
<nFieldCount
&& !bFound
; n
++ )
289 if ( nFieldArr
[n
] == nField
)
299 ScSubTotalFunc
ScTpSubTotalGroup::LbPosToFunc( sal_uInt16 nPos
)
303 // case 0: return SUBTOTAL_FUNC_NONE;
304 case 2: return SUBTOTAL_FUNC_AVE
;
305 case 6: return SUBTOTAL_FUNC_CNT
;
306 case 1: return SUBTOTAL_FUNC_CNT2
;
307 case 3: return SUBTOTAL_FUNC_MAX
;
308 case 4: return SUBTOTAL_FUNC_MIN
;
309 case 5: return SUBTOTAL_FUNC_PROD
;
310 case 7: return SUBTOTAL_FUNC_STD
;
311 case 8: return SUBTOTAL_FUNC_STDP
;
312 case 0: return SUBTOTAL_FUNC_SUM
;
313 case 9: return SUBTOTAL_FUNC_VAR
;
314 case 10: return SUBTOTAL_FUNC_VARP
;
316 OSL_FAIL( "ScTpSubTotalGroup::LbPosToFunc" );
317 return SUBTOTAL_FUNC_NONE
;
321 sal_uInt16
ScTpSubTotalGroup::FuncToLbPos( ScSubTotalFunc eFunc
)
325 // case SUBTOTAL_FUNC_NONE: return 0;
326 case SUBTOTAL_FUNC_AVE
: return 2;
327 case SUBTOTAL_FUNC_CNT
: return 6;
328 case SUBTOTAL_FUNC_CNT2
: return 1;
329 case SUBTOTAL_FUNC_MAX
: return 3;
330 case SUBTOTAL_FUNC_MIN
: return 4;
331 case SUBTOTAL_FUNC_PROD
: return 5;
332 case SUBTOTAL_FUNC_STD
: return 7;
333 case SUBTOTAL_FUNC_STDP
: return 8;
334 case SUBTOTAL_FUNC_SUM
: return 0;
335 case SUBTOTAL_FUNC_VAR
: return 9;
336 case SUBTOTAL_FUNC_VARP
: return 10;
338 OSL_FAIL( "ScTpSubTotalGroup::FuncToLbPos" );
345 IMPL_LINK( ScTpSubTotalGroup
, SelectHdl
, void *, pLb
)
347 if ( (mpLbColumns
->GetEntryCount() > 0)
348 && (mpLbColumns
->GetSelectionCount() > 0) )
350 sal_uInt16 nFunction
= mpLbFunctions
->GetSelectEntryPos();
351 sal_uInt16 nColumn
= mpLbColumns
->GetSelectEntryPos();
352 sal_uInt16
* pFunction
= static_cast<sal_uInt16
*>(mpLbColumns
->GetEntryData( nColumn
));
354 OSL_ENSURE( pFunction
, "EntryData not found!" );
358 if ( pLb
== mpLbColumns
)
360 mpLbFunctions
->SelectEntryPos( *pFunction
);
362 else if ( pLb
== mpLbFunctions
)
364 *pFunction
= nFunction
;
365 mpLbColumns
->CheckEntryPos( nColumn
, true );
371 IMPL_LINK( ScTpSubTotalGroup
, CheckHdl
, void *, pLb
)
373 if ( pLb
== mpLbColumns
)
375 SvTreeListEntry
* pEntry
= mpLbColumns
->GetHdlEntry();
379 mpLbColumns
->SelectEntryPos( (sal_uInt16
)mpLbColumns
->GetModel()->GetAbsPos( pEntry
) );
386 // Derived Group TabPages:
388 VclPtr
<SfxTabPage
> ScTpSubTotalGroup1::Create( vcl::Window
* pParent
,
389 const SfxItemSet
* rArgSet
)
391 return VclPtr
<ScTpSubTotalGroup1
>::Create( pParent
, *rArgSet
);
394 VclPtr
<SfxTabPage
> ScTpSubTotalGroup2::Create( vcl::Window
* pParent
,
395 const SfxItemSet
* rArgSet
)
397 return VclPtr
<ScTpSubTotalGroup2
>::Create( pParent
, *rArgSet
);
400 VclPtr
<SfxTabPage
> ScTpSubTotalGroup3::Create( vcl::Window
* pParent
,
401 const SfxItemSet
* rArgSet
)
403 return VclPtr
<ScTpSubTotalGroup3
>::Create( pParent
, *rArgSet
);
406 ScTpSubTotalGroup1::ScTpSubTotalGroup1( vcl::Window
* pParent
, const SfxItemSet
& rArgSet
) :
407 ScTpSubTotalGroup( pParent
, rArgSet
)
410 ScTpSubTotalGroup2::ScTpSubTotalGroup2( vcl::Window
* pParent
, const SfxItemSet
& rArgSet
) :
411 ScTpSubTotalGroup( pParent
, rArgSet
)
414 ScTpSubTotalGroup3::ScTpSubTotalGroup3( vcl::Window
* pParent
, const SfxItemSet
& rArgSet
) :
415 ScTpSubTotalGroup( pParent
, rArgSet
)
418 #define RESET(i) (ScTpSubTotalGroup::DoReset( (i), *rArgSet ))
419 void ScTpSubTotalGroup1::Reset( const SfxItemSet
* rArgSet
) { RESET(1); }
420 void ScTpSubTotalGroup2::Reset( const SfxItemSet
* rArgSet
) { RESET(2); }
421 void ScTpSubTotalGroup3::Reset( const SfxItemSet
* rArgSet
) { RESET(3); }
424 #define FILLSET(i) (ScTpSubTotalGroup::DoFillItemSet( (i), *rArgSet ))
425 bool ScTpSubTotalGroup1::FillItemSet( SfxItemSet
* rArgSet
) { return FILLSET(1); }
426 bool ScTpSubTotalGroup2::FillItemSet( SfxItemSet
* rArgSet
) { return FILLSET(2); }
427 bool ScTpSubTotalGroup3::FillItemSet( SfxItemSet
* rArgSet
) { return FILLSET(3); }
432 ScTpSubTotalOptions::ScTpSubTotalOptions( vcl::Window
* pParent
,
433 const SfxItemSet
& rArgSet
)
435 : SfxTabPage ( pParent
,
436 "SubTotalOptionsPage", "modules/scalc/ui/subtotaloptionspage.ui" ,
440 nWhichSubTotals ( rArgSet
.GetPool()->GetWhich( SID_SUBTOTALS
) ),
441 rSubTotalData ( static_cast<const ScSubTotalItem
&>(
442 rArgSet
.Get( nWhichSubTotals
)).
445 get(pBtnPagebreak
,"pagebreak");
446 get(pBtnCase
,"case");
447 get(pBtnSort
,"sort");
448 get(pFlSort
,"label2");
449 get(pBtnAscending
,"ascending");
450 get(pBtnDescending
,"descending");
451 get(pBtnFormats
,"formats");
452 get(pBtnUserDef
,"btnuserdef");
453 get(pLbUserDef
,"lbuserdef");
458 ScTpSubTotalOptions::~ScTpSubTotalOptions()
463 void ScTpSubTotalOptions::dispose()
465 pBtnPagebreak
.clear();
469 pBtnAscending
.clear();
470 pBtnDescending
.clear();
474 SfxTabPage::dispose();
477 void ScTpSubTotalOptions::Init()
479 const ScSubTotalItem
& rSubTotalItem
= static_cast<const ScSubTotalItem
&>(
480 GetItemSet().Get( nWhichSubTotals
));
482 pViewData
= rSubTotalItem
.GetViewData();
483 pDoc
= ( pViewData
) ? pViewData
->GetDocument() : NULL
;
485 OSL_ENSURE( pViewData
&& pDoc
, "ViewData or Document not found!" );
487 pBtnSort
->SetClickHdl ( LINK( this, ScTpSubTotalOptions
, CheckHdl
) );
488 pBtnUserDef
->SetClickHdl ( LINK( this, ScTpSubTotalOptions
, CheckHdl
) );
490 FillUserSortListBox();
493 VclPtr
<SfxTabPage
> ScTpSubTotalOptions::Create( vcl::Window
* pParent
,
494 const SfxItemSet
* rArgSet
)
496 return VclPtr
<ScTpSubTotalOptions
>::Create( pParent
, *rArgSet
);
499 void ScTpSubTotalOptions::Reset( const SfxItemSet
* /* rArgSet */ )
501 pBtnPagebreak
->Check ( rSubTotalData
.bPagebreak
);
502 pBtnCase
->Check ( rSubTotalData
.bCaseSens
);
503 pBtnFormats
->Check ( rSubTotalData
.bIncludePattern
);
504 pBtnSort
->Check ( rSubTotalData
.bDoSort
);
505 pBtnAscending
->Check ( rSubTotalData
.bAscending
);
506 pBtnDescending
->Check( !rSubTotalData
.bAscending
);
508 if ( rSubTotalData
.bUserDef
)
510 pBtnUserDef
->Check( true );
511 pLbUserDef
->Enable();
512 pLbUserDef
->SelectEntryPos( rSubTotalData
.nUserIndex
);
516 pBtnUserDef
->Check( false );
517 pLbUserDef
->Disable();
518 pLbUserDef
->SelectEntryPos( 0 );
521 CheckHdl( pBtnSort
);
524 bool ScTpSubTotalOptions::FillItemSet( SfxItemSet
* rArgSet
)
526 ScSubTotalParam theSubTotalData
; // auslesen, wenn schon teilweise gefuellt
527 SfxTabDialog
* pDlg
= GetTabDialog();
530 const SfxItemSet
* pExample
= pDlg
->GetExampleSet();
531 const SfxPoolItem
* pItem
;
532 if ( pExample
&& pExample
->GetItemState( nWhichSubTotals
, true, &pItem
) == SfxItemState::SET
)
533 theSubTotalData
= static_cast<const ScSubTotalItem
*>(pItem
)->GetSubTotalData();
536 theSubTotalData
.bPagebreak
= pBtnPagebreak
->IsChecked();
537 theSubTotalData
.bReplace
= true;
538 theSubTotalData
.bCaseSens
= pBtnCase
->IsChecked();
539 theSubTotalData
.bIncludePattern
= pBtnFormats
->IsChecked();
540 theSubTotalData
.bDoSort
= pBtnSort
->IsChecked();
541 theSubTotalData
.bAscending
= pBtnAscending
->IsChecked();
542 theSubTotalData
.bUserDef
= pBtnUserDef
->IsChecked();
543 theSubTotalData
.nUserIndex
= (pBtnUserDef
->IsChecked())
544 ? pLbUserDef
->GetSelectEntryPos()
547 rArgSet
->Put( ScSubTotalItem( nWhichSubTotals
, &theSubTotalData
) );
552 void ScTpSubTotalOptions::FillUserSortListBox()
554 ScUserList
* pUserLists
= ScGlobal::GetUserList();
559 size_t nCount
= pUserLists
->size();
560 for ( size_t i
=0; i
<nCount
; ++i
)
561 pLbUserDef
->InsertEntry( (*pUserLists
)[i
]->GetString() );
567 IMPL_LINK( ScTpSubTotalOptions
, CheckHdl
, CheckBox
*, pBox
)
569 if ( pBox
== pBtnSort
)
571 if ( pBtnSort
->IsChecked() )
574 pBtnFormats
->Enable();
575 pBtnUserDef
->Enable();
576 pBtnAscending
->Enable();
577 pBtnDescending
->Enable();
579 if ( pBtnUserDef
->IsChecked() )
580 pLbUserDef
->Enable();
585 pBtnFormats
->Disable();
586 pBtnUserDef
->Disable();
587 pBtnAscending
->Disable();
588 pBtnDescending
->Disable();
589 pLbUserDef
->Disable();
592 else if ( pBox
== pBtnUserDef
)
594 if ( pBtnUserDef
->IsChecked() )
596 pLbUserDef
->Enable();
597 pLbUserDef
->GrabFocus();
600 pLbUserDef
->Disable();
606 ScTpSubTotalGroup1::~ScTpSubTotalGroup1()
610 ScTpSubTotalGroup2::~ScTpSubTotalGroup2()
614 ScTpSubTotalGroup3::~ScTpSubTotalGroup3()
618 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */