Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / sc / source / ui / dbgui / tpsubt.cxx
blobd2c53569f760076985b5e53e82c73e9150be7d0e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
24 #include "global.hxx"
25 #include "userlist.hxx"
26 #include "viewdata.hxx"
27 #include "document.hxx"
28 #include "scresid.hxx"
29 #include "sc.hrc"
31 #include "subtdlg.hxx"
32 #include "tpsubt.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",
41 rArgSet ),
42 aStrNone ( SC_RESSTR( SCSTR_NONE ) ),
43 aStrColumn ( SC_RESSTR( SCSTR_COLUMN ) ),
44 pViewData ( NULL ),
45 pDoc ( NULL ),
46 nWhichSubTotals ( rArgSet.GetPool()->GetWhich( SID_SUBTOTALS ) ),
47 rSubTotalData ( ((const ScSubTotalItem&)
48 rArgSet.Get( nWhichSubTotals )).
49 GetSubTotalData() ),
50 nFieldCount ( 0 )
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 );
65 Init ();
68 ScTpSubTotalGroup::~ScTpSubTotalGroup()
70 sal_uLong nCount = mpLbColumns->GetEntryCount();
72 if ( nCount > 0 )
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" );
81 delete pData;
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 ) );
101 nFieldArr[0] = 0;
102 FillListBoxes();
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) )
113 return false;
114 else
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 )).
127 GetSubTotalData() );
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);
153 else
155 mpLbGroup->SelectEntryPos( (nGroupNo == 1) ? 1 : 0 );
156 mpLbColumns->SelectEntryPos( 0 );
157 mpLbFunctions->SelectEntryPos( 0 );
160 return true;
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)
180 return false;
181 else
182 nGroupIdx = nGroupNo-1;
184 ScSubTotalParam theSubTotalData; // auslesen, wenn schon teilweise gefuellt
185 SfxTabDialog* pDlg = GetTabDialog();
186 if ( pDlg )
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,
221 "Range error :-(" );
222 nFunction = *((sal_uInt16*)mpLbColumns->GetEntryData( i ));
223 pSubTotals[nCheck] = nFieldArr[i];
224 pFunctions[nCheck] = LbPosToFunc( nFunction );
225 nCheck++;
228 theSubTotalData.SetSubTotals( nGroupNo, // Gruppen-Nr.
229 pSubTotals.get(),
230 pFunctions.get(),
231 nCheckCount ); // Anzahl der Array-Elemente
235 rArgSet.Put( ScSubTotalItem( SCITEM_SUBTDATA, &theSubTotalData ) );
237 return true;
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;
250 SCCOL col;
251 OUString aFieldName;
253 mpLbGroup->Clear();
254 mpLbColumns->Clear();
255 mpLbGroup->InsertEntry( aStrNone, 0 );
257 sal_uInt16 i=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 ));
265 nFieldArr[i] = col;
266 mpLbGroup->InsertEntry( aFieldName, i+1 );
267 mpLbColumns->InsertEntry( aFieldName, i );
268 mpLbColumns->SetEntryData( i, new sal_uInt16(0) );
269 i++;
271 // subsequent initialization of the constant:
272 (sal_uInt16&)nFieldCount = i;
276 sal_uInt16 ScTpSubTotalGroup::GetFieldSelPos( SCCOL nField )
278 sal_uInt16 nFieldPos = 0;
279 bool bFound = false;
281 for ( sal_uInt16 n=0; n<nFieldCount && !bFound; n++ )
283 if ( nFieldArr[n] == nField )
285 nFieldPos = n;
286 bFound = true;
290 return nFieldPos;
293 ScSubTotalFunc ScTpSubTotalGroup::LbPosToFunc( sal_uInt16 nPos )
295 switch ( 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;
309 default:
310 OSL_FAIL( "ScTpSubTotalGroup::LbPosToFunc" );
311 return SUBTOTAL_FUNC_NONE;
315 sal_uInt16 ScTpSubTotalGroup::FuncToLbPos( ScSubTotalFunc eFunc )
317 switch ( 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;
331 default:
332 OSL_FAIL( "ScTpSubTotalGroup::FuncToLbPos" );
333 return 0;
338 // Handler:
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!" );
351 if ( !pFunction )
352 return 0;
354 if ( ((SvxCheckListBox*)pLb) == mpLbColumns )
356 mpLbFunctions->SelectEntryPos( *pFunction );
358 else if ( pLb == mpLbFunctions )
360 *pFunction = nFunction;
361 mpLbColumns->CheckEntryPos( nColumn, true );
364 return 0;
367 IMPL_LINK( ScTpSubTotalGroup, CheckHdl, ListBox *, pLb )
369 if ( ((SvxCheckListBox*)pLb) == mpLbColumns )
371 SvTreeListEntry* pEntry = mpLbColumns->GetHdlEntry();
373 if ( pEntry )
375 mpLbColumns->SelectEntryPos( (sal_uInt16)mpLbColumns->GetModel()->GetAbsPos( pEntry ) );
376 SelectHdl( pLb );
379 return 0;
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); }
414 #undef RESET
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); }
420 #undef FILL
423 // Optionen-Tabpage:
425 ScTpSubTotalOptions::ScTpSubTotalOptions( Window* pParent,
426 const SfxItemSet& rArgSet )
428 : SfxTabPage ( pParent,
429 "SubTotalOptionsPage", "modules/scalc/ui/subtotaloptionspage.ui" ,
430 rArgSet ),
431 pViewData ( NULL ),
432 pDoc ( NULL ),
433 nWhichSubTotals ( rArgSet.GetPool()->GetWhich( SID_SUBTOTALS ) ),
434 rSubTotalData ( ((const ScSubTotalItem&)
435 rArgSet.Get( nWhichSubTotals )).
436 GetSubTotalData() )
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");
448 Init();
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 );
492 else
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();
506 if ( pDlg )
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()
523 : 0;
525 rArgSet.Put( ScSubTotalItem( nWhichSubTotals, &theSubTotalData ) );
527 return true;
530 void ScTpSubTotalOptions::FillUserSortListBox()
532 ScUserList* pUserLists = ScGlobal::GetUserList();
534 pLbUserDef->Clear();
535 if ( pUserLists )
537 size_t nCount = pUserLists->size();
538 for ( size_t i=0; i<nCount; ++i )
539 pLbUserDef->InsertEntry( (*pUserLists)[i]->GetString() );
544 // Handler:
546 IMPL_LINK( ScTpSubTotalOptions, CheckHdl, CheckBox *, pBox )
548 if ( pBox == pBtnSort )
550 if ( pBtnSort->IsChecked() )
552 pFlSort->Enable();
553 pBtnFormats->Enable();
554 pBtnUserDef->Enable();
555 pBtnAscending->Enable();
556 pBtnDescending->Enable();
558 if ( pBtnUserDef->IsChecked() )
559 pLbUserDef->Enable();
561 else
563 pFlSort->Disable();
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();
578 else
579 pLbUserDef->Disable();
582 return 0;
585 ScTpSubTotalGroup1::~ScTpSubTotalGroup1()
589 ScTpSubTotalGroup2::~ScTpSubTotalGroup2()
593 ScTpSubTotalGroup3::~ScTpSubTotalGroup3()
597 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */