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 #include <sfx2/dispatch.hxx>
22 #include "tabvwsh.hxx"
23 #include "uiitems.hxx"
25 #include "rangenam.hxx"
26 #include "rangeutl.hxx"
27 #include "reffact.hxx"
28 #include "document.hxx"
29 #include "scresid.hxx"
31 #include "globstr.hrc"
32 #include "consdlg.hrc"
35 #include "consdlg.hxx"
37 #include <vcl/msgbox.hxx>
39 #define INFOBOX(id) InfoBox(this, ScGlobal::GetRscString(id)).Execute()
41 //============================================================================
50 void Set( const String
& rName
, const String
& rArea
, sal_Bool bDb
)
63 //============================================================================
64 // class ScConsolidateDialog
67 ScConsolidateDlg::ScConsolidateDlg( SfxBindings
* pB
, SfxChildWindow
* pCW
, Window
* pParent
,
68 const SfxItemSet
& rArgSet
)
70 : ScAnyRefDlg ( pB
, pCW
, pParent
, RID_SCDLG_CONSOLIDATE
),
72 aFtFunc ( this, ScResId( FT_FUNC
) ),
73 aLbFunc ( this, ScResId( LB_FUNC
) ),
75 aFtConsAreas ( this, ScResId( FT_CONSAREAS
) ),
76 aLbConsAreas ( this, ScResId( LB_CONSAREAS
) ),
78 aLbDataArea ( this, ScResId( LB_DATA_AREA
) ),
79 aFtDataArea ( this, ScResId( FT_DATA_AREA
) ),
80 aEdDataArea ( this, this, &aFtDataArea
, ScResId( ED_DATA_AREA
) ),
81 aRbDataArea ( this, ScResId( RB_DATA_AREA
), &aEdDataArea
, this ),
83 aLbDestArea ( this, ScResId( LB_DEST_AREA
) ),
84 aFtDestArea ( this, ScResId( FT_DEST_AREA
) ),
85 aEdDestArea ( this, this, &aFtDestArea
, ScResId( ED_DEST_AREA
) ),
86 aRbDestArea ( this, ScResId( RB_DEST_AREA
), &aEdDestArea
, this),
88 aFlConsBy ( this, ScResId( FL_CONSBY
) ),
89 aBtnByRow ( this, ScResId( BTN_BYROW
) ),
90 aBtnByCol ( this, ScResId( BTN_BYCOL
) ),
92 aFlSep ( this, ScResId( FL_SEP
) ),
93 aFlOptions ( this, ScResId( FL_OPTIONS
) ),
94 aBtnRefs ( this, ScResId( BTN_REFS
) ),
96 aBtnOk ( this, ScResId( BTN_OK
) ),
97 aBtnCancel ( this, ScResId( BTN_CANCEL
) ),
98 aBtnHelp ( this, ScResId( BTN_HELP
) ),
99 aBtnAdd ( this, ScResId( BTN_ADD
) ),
100 aBtnRemove ( this, ScResId( BTN_REMOVE
) ),
101 aBtnMore ( this, ScResId( BTN_MORE
) ),
103 aStrUndefined ( ScResId( SCSTR_UNDEFINED
) ),
105 theConsData ( ((const ScConsolidateItem
&)
106 rArgSet
.Get( rArgSet
.GetPool()->
107 GetWhich( SID_CONSOLIDATE
) )
109 pViewData ( ((ScTabViewShell
*)SfxViewShell::Current())->
111 pDoc ( ((ScTabViewShell
*)SfxViewShell::Current())->
112 GetViewData()->GetDocument() ),
113 pRangeUtil ( new ScRangeUtil
),
115 nAreaDataCount ( 0 ),
116 nWhichCons ( rArgSet
.GetPool()->GetWhich( SID_CONSOLIDATE
) ),
118 pRefInputEdit ( &aEdDataArea
)
125 //----------------------------------------------------------------------------
127 ScConsolidateDlg::~ScConsolidateDlg()
134 //----------------------------------------------------------------------------
136 void ScConsolidateDlg::Init()
138 OSL_ENSURE( pViewData
&& pDoc
&& pRangeUtil
, "Error in Ctor" );
143 aEdDataArea
.SetGetFocusHdl( LINK( this, ScConsolidateDlg
, GetFocusHdl
) );
144 aEdDestArea
.SetGetFocusHdl( LINK( this, ScConsolidateDlg
, GetFocusHdl
) );
145 aLbDataArea
.SetGetFocusHdl( LINK( this, ScConsolidateDlg
, GetFocusHdl
) );
146 aLbDestArea
.SetGetFocusHdl( LINK( this, ScConsolidateDlg
, GetFocusHdl
) );
147 aEdDataArea
.SetModifyHdl ( LINK( this, ScConsolidateDlg
, ModifyHdl
) );
148 aEdDestArea
.SetModifyHdl ( LINK( this, ScConsolidateDlg
, ModifyHdl
) );
149 aLbConsAreas
.SetSelectHdl ( LINK( this, ScConsolidateDlg
, SelectHdl
) );
150 aLbDataArea
.SetSelectHdl ( LINK( this, ScConsolidateDlg
, SelectHdl
) );
151 aLbDestArea
.SetSelectHdl ( LINK( this, ScConsolidateDlg
, SelectHdl
) );
152 aBtnOk
.SetClickHdl ( LINK( this, ScConsolidateDlg
, OkHdl
) );
153 aBtnCancel
.SetClickHdl ( LINK( this, ScConsolidateDlg
, ClickHdl
) );
154 aBtnAdd
.SetClickHdl ( LINK( this, ScConsolidateDlg
, ClickHdl
) );
155 aBtnRemove
.SetClickHdl ( LINK( this, ScConsolidateDlg
, ClickHdl
) );
157 aBtnMore
.AddWindow( &aFlConsBy
);
158 aBtnMore
.AddWindow( &aBtnByRow
);
159 aBtnMore
.AddWindow( &aBtnByCol
);
160 aBtnMore
.AddWindow( &aFlSep
);
161 aBtnMore
.AddWindow( &aFlOptions
);
162 aBtnMore
.AddWindow( &aBtnRefs
);
165 aBtnRemove
.Disable();
167 aBtnByRow
.Check( theConsData
.bByRow
);
168 aBtnByCol
.Check( theConsData
.bByCol
);
169 aBtnRefs
.Check( theConsData
.bReferenceData
);
171 aLbFunc
.SelectEntryPos( FuncToLbPos( theConsData
.eFunction
) );
173 // Einlesen der Konsolidierungsbereiche
174 aLbConsAreas
.Clear();
175 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
176 for ( i
=0; i
<theConsData
.nDataAreaCount
; i
++ )
178 const ScArea
& rArea
= *(theConsData
.ppDataAreas
[i
] );
179 if ( rArea
.nTab
< pDoc
->GetTableCount() )
181 ScRange( rArea
.nColStart
, rArea
.nRowStart
, rArea
.nTab
,
182 rArea
.nColEnd
, rArea
.nRowEnd
, rArea
.nTab
).Format( aStr
,
183 SCR_ABS_3D
, pDoc
, eConv
);
184 aLbConsAreas
.InsertEntry( aStr
);
188 if ( theConsData
.nTab
< pDoc
->GetTableCount() )
190 ScAddress( theConsData
.nCol
, theConsData
.nRow
, theConsData
.nTab
191 ).Format( aStr
, SCA_ABS_3D
, pDoc
, eConv
);
192 aEdDestArea
.SetText( aStr
);
195 aEdDestArea
.SetText( EMPTY_STRING
);
197 //----------------------------------------------------------
200 * Aus den RangeNames und Datenbankbereichen werden sich
201 * in der Hilfsklasse ScAreaData die Bereichsnamen gemerkt,
202 * die in den ListBoxen erscheinen.
205 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
206 ScDBCollection
* pDbNames
= pDoc
->GetDBCollection();
207 size_t nRangeCount
= pRangeNames
? pRangeNames
->size() : 0;
208 size_t nDbCount
= pDbNames
? pDbNames
->getNamedDBs().size() : 0;
210 nAreaDataCount
= nRangeCount
+nDbCount
;
213 if ( nAreaDataCount
> 0 )
215 pAreaData
= new ScAreaData
[nAreaDataCount
];
221 ScAreaNameIterator
aIter( pDoc
);
222 while ( aIter
.Next( aStrName
, aRange
) )
224 aRange
.Format( aStrArea
, SCA_ABS_3D
, pDoc
, eConv
);
225 pAreaData
[nAt
++].Set( aStrName
, aStrArea
, aIter
.WasDBName() );
230 ModifyHdl( &aEdDestArea
);
231 aLbDataArea
.SelectEntryPos( 0 );
232 aEdDataArea
.SetText( EMPTY_STRING
);
233 aEdDataArea
.GrabFocus();
235 aFlSep
.SetStyle( aFlSep
.GetStyle() | WB_VERT
);
237 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
238 //SFX_APPWINDOW->Enable();
242 //----------------------------------------------------------------------------
243 void ScConsolidateDlg::FillAreaLists()
247 aLbDataArea
.InsertEntry( aStrUndefined
);
248 aLbDestArea
.InsertEntry( aStrUndefined
);
250 if ( pRangeUtil
&& pAreaData
&& (nAreaDataCount
> 0) )
253 (i
<nAreaDataCount
) && (pAreaData
[i
].aStrName
.Len()>0);
256 aLbDataArea
.InsertEntry( pAreaData
[i
].aStrName
, i
+1 );
258 // if ( !pAreaData[i].bIsDbArea )
259 aLbDestArea
.InsertEntry( pAreaData
[i
].aStrName
, i
+1 );
265 //----------------------------------------------------------------------------
266 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
267 // neue Selektion im Referenz-Fenster angezeigt wird.
270 void ScConsolidateDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
274 if ( rRef
.aStart
!= rRef
.aEnd
)
275 RefInputStart( pRefInputEdit
);
278 sal_uInt16 nFmt
= SCR_ABS_3D
; //!!! nCurTab fehlt noch
279 const formula::FormulaGrammar::AddressConvention eConv
= pDocP
->GetAddressConvention();
281 if ( rRef
.aStart
.Tab() != rRef
.aEnd
.Tab() )
284 if ( pRefInputEdit
== &aEdDataArea
)
285 rRef
.Format( aStr
, nFmt
, pDocP
, eConv
);
286 else if ( pRefInputEdit
== &aEdDestArea
)
287 rRef
.aStart
.Format( aStr
, nFmt
, pDocP
, eConv
);
289 pRefInputEdit
->SetRefString( aStr
);
292 ModifyHdl( pRefInputEdit
);
296 //----------------------------------------------------------------------------
298 sal_Bool
ScConsolidateDlg::Close()
300 return DoClose( ScConsolidateDlgWrapper::GetChildWindowId() );
304 //----------------------------------------------------------------------------
306 void ScConsolidateDlg::SetActive()
310 bDlgLostFocus
= false;
314 pRefInputEdit
->GrabFocus();
315 ModifyHdl( pRefInputEdit
);
325 //----------------------------------------------------------------------------
327 void ScConsolidateDlg::Deactivate()
329 bDlgLostFocus
= sal_True
;
333 //----------------------------------------------------------------------------
335 sal_Bool
ScConsolidateDlg::VerifyEdit( formula::RefEdit
* pEd
)
337 if ( !pRangeUtil
|| !pDoc
|| !pViewData
||
338 ((pEd
!= &aEdDataArea
) && (pEd
!= &aEdDestArea
)) )
341 SCTAB nTab
= pViewData
->GetTabNo();
342 sal_Bool bEditOk
= false;
343 String theCompleteStr
;
344 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
346 if ( pEd
== &aEdDataArea
)
348 bEditOk
= pRangeUtil
->IsAbsArea( pEd
->GetText(), pDoc
,
349 nTab
, &theCompleteStr
, NULL
, NULL
, eConv
);
351 else if ( pEd
== &aEdDestArea
)
355 pRangeUtil
->CutPosString( pEd
->GetText(), aPosStr
);
356 bEditOk
= pRangeUtil
->IsAbsPos( aPosStr
, pDoc
,
357 nTab
, &theCompleteStr
, NULL
, eConv
);
361 pEd
->SetText( theCompleteStr
);
367 //----------------------------------------------------------------------------
371 IMPL_LINK( ScConsolidateDlg
, GetFocusHdl
, Control
*, pCtr
)
373 if ( pCtr
==(Control
*)&aEdDataArea
||
374 pCtr
==(Control
*)&aEdDestArea
)
376 pRefInputEdit
= (formula::RefEdit
*)pCtr
;
378 else if(pCtr
==(Control
*)&aLbDataArea
)
380 pRefInputEdit
= &aEdDataArea
;
382 else if(pCtr
==(Control
*)&aLbDestArea
)
384 pRefInputEdit
= &aEdDestArea
;
390 //----------------------------------------------------------------------------
392 IMPL_LINK_NOARG(ScConsolidateDlg
, OkHdl
)
394 sal_uInt16 nDataAreaCount
= aLbConsAreas
.GetEntryCount();
396 if ( nDataAreaCount
> 0 )
398 ScRefAddress aDestAddress
;
399 SCTAB nTab
= pViewData
->GetTabNo();
400 String
aDestPosStr( aEdDestArea
.GetText() );
401 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
403 if ( pRangeUtil
->IsAbsPos( aDestPosStr
, pDoc
, nTab
, NULL
, &aDestAddress
, eConv
) )
405 ScConsolidateParam
theOutParam( theConsData
);
406 ScArea
** ppDataAreas
= new ScArea
*[nDataAreaCount
];
410 for ( i
=0; i
<nDataAreaCount
; i
++ )
413 pRangeUtil
->MakeArea( aLbConsAreas
.GetEntry( i
),
414 *pArea
, pDoc
, nTab
, eConv
);
415 ppDataAreas
[i
] = pArea
;
418 theOutParam
.nCol
= aDestAddress
.Col();
419 theOutParam
.nRow
= aDestAddress
.Row();
420 theOutParam
.nTab
= aDestAddress
.Tab();
421 theOutParam
.eFunction
= LbPosToFunc( aLbFunc
.GetSelectEntryPos() );
422 theOutParam
.bByCol
= aBtnByCol
.IsChecked();
423 theOutParam
.bByRow
= aBtnByRow
.IsChecked();
424 theOutParam
.bReferenceData
= aBtnRefs
.IsChecked();
425 theOutParam
.SetAreas( ppDataAreas
, nDataAreaCount
);
427 for ( i
=0; i
<nDataAreaCount
; i
++ )
428 delete ppDataAreas
[i
];
429 delete [] ppDataAreas
;
431 ScConsolidateItem
aOutItem( nWhichCons
, &theOutParam
);
433 SetDispatcherLock( false );
435 GetBindings().GetDispatcher()->Execute( SID_CONSOLIDATE
,
436 SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
,
442 INFOBOX( STR_INVALID_TABREF
);
443 aEdDestArea
.GrabFocus();
447 Close(); // keine Datenbereiche definiert -> Cancel
452 //----------------------------------------------------------------------------
454 IMPL_LINK( ScConsolidateDlg
, ClickHdl
, PushButton
*, pBtn
)
456 if ( pBtn
== &aBtnCancel
)
458 else if ( pBtn
== &aBtnAdd
)
460 if ( !aEdDataArea
.GetText().isEmpty() )
462 String
aNewEntry( aEdDataArea
.GetText() );
463 ScArea
** ppAreas
= NULL
;
464 sal_uInt16 nAreaCount
= 0;
465 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
467 if ( pRangeUtil
->IsAbsTabArea( aNewEntry
, pDoc
, &ppAreas
, &nAreaCount
, sal_True
, eConv
) )
469 // IsAbsTabArea() legt ein Array von ScArea-Zeigern an,
470 // welche ebenfalls dynamisch erzeugt wurden.
471 // Diese Objekte muessen hier abgeraeumt werden.
473 for ( sal_uInt16 i
=0; i
<nAreaCount
; i
++ )
479 const ScArea
& rArea
= *(ppAreas
[i
]);
480 ScRange( rArea
.nColStart
, rArea
.nRowStart
, rArea
.nTab
,
481 rArea
.nColEnd
, rArea
.nRowEnd
, rArea
.nTab
482 ).Format( aNewArea
, SCR_ABS_3D
, pDoc
, eConv
);
484 if ( aLbConsAreas
.GetEntryPos( aNewArea
)
485 == LISTBOX_ENTRY_NOTFOUND
)
487 aLbConsAreas
.InsertEntry( aNewArea
);
494 else if ( VerifyEdit( &aEdDataArea
) )
496 String
aNewArea( aEdDataArea
.GetText() );
498 if ( aLbConsAreas
.GetEntryPos( aNewArea
) == LISTBOX_ENTRY_NOTFOUND
)
499 aLbConsAreas
.InsertEntry( aNewArea
);
501 INFOBOX( STR_AREA_ALREADY_INSERTED
);
505 INFOBOX( STR_INVALID_TABREF
);
506 aEdDataArea
.GrabFocus();
510 else if ( pBtn
== &aBtnRemove
)
512 while ( aLbConsAreas
.GetSelectEntryCount() )
513 aLbConsAreas
.RemoveEntry( aLbConsAreas
.GetSelectEntryPos() );
514 aBtnRemove
.Disable();
520 //----------------------------------------------------------------------------
522 IMPL_LINK( ScConsolidateDlg
, SelectHdl
, ListBox
*, pLb
)
524 if ( pLb
== &aLbConsAreas
)
526 if ( aLbConsAreas
.GetSelectEntryCount() > 0 )
529 aBtnRemove
.Disable();
531 else if ( (pLb
== &aLbDataArea
) || (pLb
== &aLbDestArea
) )
533 Edit
* pEd
= (pLb
== &aLbDataArea
) ? &aEdDataArea
: &aEdDestArea
;
534 sal_uInt16 nSelPos
= pLb
->GetSelectEntryPos();
538 && (nAreaDataCount
> 0)
539 && (pAreaData
!= NULL
) )
541 if ( static_cast<size_t>(nSelPos
) <= nAreaDataCount
)
543 String
aString( pAreaData
[nSelPos
-1].aStrArea
);
545 if ( pLb
== &aLbDestArea
)
546 pRangeUtil
->CutPosString( aString
, aString
);
548 pEd
->SetText( aString
);
550 if ( pEd
== &aEdDataArea
)
556 pEd
->SetText( EMPTY_STRING
);
557 if ( pEd
== &aEdDataArea
)
565 //----------------------------------------------------------------------------
567 IMPL_LINK( ScConsolidateDlg
, ModifyHdl
, formula::RefEdit
*, pEd
)
569 if ( pEd
== &aEdDataArea
)
571 String
aAreaStr( pEd
->GetText() );
572 if ( aAreaStr
.Len() > 0 )
579 else if ( pEd
== &aEdDestArea
)
581 aLbDestArea
.SelectEntryPos(0);
587 //----------------------------------------------------------------------------
588 // Verallgemeinern!!! :
589 // Resource der ListBox und diese beiden Umrechnungsmethoden gibt es
590 // auch noch in tpsubt bzw. ueberall, wo StarCalc-Funktionen
593 ScSubTotalFunc
ScConsolidateDlg::LbPosToFunc( sal_uInt16 nPos
)
597 case 2: return SUBTOTAL_FUNC_AVE
;
598 case 6: return SUBTOTAL_FUNC_CNT
;
599 case 1: return SUBTOTAL_FUNC_CNT2
;
600 case 3: return SUBTOTAL_FUNC_MAX
;
601 case 4: return SUBTOTAL_FUNC_MIN
;
602 case 5: return SUBTOTAL_FUNC_PROD
;
603 case 7: return SUBTOTAL_FUNC_STD
;
604 case 8: return SUBTOTAL_FUNC_STDP
;
605 case 9: return SUBTOTAL_FUNC_VAR
;
606 case 10: return SUBTOTAL_FUNC_VARP
;
609 return SUBTOTAL_FUNC_SUM
;
614 //----------------------------------------------------------------------------
616 sal_uInt16
ScConsolidateDlg::FuncToLbPos( ScSubTotalFunc eFunc
)
620 case SUBTOTAL_FUNC_AVE
: return 2;
621 case SUBTOTAL_FUNC_CNT
: return 6;
622 case SUBTOTAL_FUNC_CNT2
: return 1;
623 case SUBTOTAL_FUNC_MAX
: return 3;
624 case SUBTOTAL_FUNC_MIN
: return 4;
625 case SUBTOTAL_FUNC_PROD
: return 5;
626 case SUBTOTAL_FUNC_STD
: return 7;
627 case SUBTOTAL_FUNC_STDP
: return 8;
628 case SUBTOTAL_FUNC_VAR
: return 9;
629 case SUBTOTAL_FUNC_VARP
: return 10;
630 case SUBTOTAL_FUNC_NONE
:
631 case SUBTOTAL_FUNC_SUM
:
637 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */