bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / dbgui / consdlg.cxx
blobaa85cbed3b3bcf5a0b9a6c6b73dd0c884b67de6d
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 #include <sfx2/dispatch.hxx>
22 #include "tabvwsh.hxx"
23 #include "uiitems.hxx"
24 #include "dbdata.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"
34 #define _CONSDLG_CXX
35 #include "consdlg.hxx"
36 #undef _CONSDLG_CXX
37 #include <vcl/msgbox.hxx>
39 #define INFOBOX(id) InfoBox(this, ScGlobal::GetRscString(id)).Execute()
41 //============================================================================
42 // class ScAreaData
44 class ScAreaData
46 public:
47 ScAreaData() {}
48 ~ScAreaData() {}
50 void Set( const String& rName, const String& rArea, sal_Bool bDb )
52 aStrName = rName;
53 aStrArea = rArea;
54 bIsDbArea = bDb;
57 String aStrName;
58 String aStrArea;
59 sal_Bool bIsDbArea;
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 ) )
108 ).GetData() ),
109 pViewData ( ((ScTabViewShell*)SfxViewShell::Current())->
110 GetViewData() ),
111 pDoc ( ((ScTabViewShell*)SfxViewShell::Current())->
112 GetViewData()->GetDocument() ),
113 pRangeUtil ( new ScRangeUtil ),
114 pAreaData ( NULL ),
115 nAreaDataCount ( 0 ),
116 nWhichCons ( rArgSet.GetPool()->GetWhich( SID_CONSOLIDATE ) ),
118 pRefInputEdit ( &aEdDataArea )
120 Init();
121 FreeResource();
125 //----------------------------------------------------------------------------
127 ScConsolidateDlg::~ScConsolidateDlg()
129 delete [] pAreaData;
130 delete pRangeUtil;
134 //----------------------------------------------------------------------------
136 void ScConsolidateDlg::Init()
138 OSL_ENSURE( pViewData && pDoc && pRangeUtil, "Error in Ctor" );
140 String aStr;
141 sal_uInt16 i=0;
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 );
164 aBtnAdd.Disable();
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 );
194 else
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;
211 pAreaData = NULL;
213 if ( nAreaDataCount > 0 )
215 pAreaData = new ScAreaData[nAreaDataCount];
217 String aStrName;
218 String aStrArea;
219 sal_uInt16 nAt = 0;
220 ScRange aRange;
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() );
229 FillAreaLists();
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()
245 aLbDataArea.Clear();
246 aLbDestArea.Clear();
247 aLbDataArea.InsertEntry( aStrUndefined );
248 aLbDestArea.InsertEntry( aStrUndefined );
250 if ( pRangeUtil && pAreaData && (nAreaDataCount > 0) )
252 for ( size_t i=0;
253 (i<nAreaDataCount) && (pAreaData[i].aStrName.Len()>0);
254 i++ )
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 )
272 if ( pRefInputEdit )
274 if ( rRef.aStart != rRef.aEnd )
275 RefInputStart( pRefInputEdit );
277 String aStr;
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() )
282 nFmt |= SCA_TAB2_3D;
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()
308 if ( bDlgLostFocus )
310 bDlgLostFocus = false;
312 if ( pRefInputEdit )
314 pRefInputEdit->GrabFocus();
315 ModifyHdl( pRefInputEdit );
318 else
319 GrabFocus();
321 RefInputDone();
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)) )
339 return false;
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 )
353 String aPosStr;
355 pRangeUtil->CutPosString( pEd->GetText(), aPosStr );
356 bEditOk = pRangeUtil->IsAbsPos( aPosStr, pDoc,
357 nTab, &theCompleteStr, NULL, eConv );
360 if ( bEditOk )
361 pEd->SetText( theCompleteStr );
363 return bEditOk;
367 //----------------------------------------------------------------------------
368 // Handler:
369 // ========
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;
386 return 0;
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];
407 ScArea* pArea;
408 sal_uInt16 i=0;
410 for ( i=0; i<nDataAreaCount; i++ )
412 pArea = new ScArea;
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 );
434 SwitchToDocument();
435 GetBindings().GetDispatcher()->Execute( SID_CONSOLIDATE,
436 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
437 &aOutItem, 0L, 0L );
438 Close();
440 else
442 INFOBOX( STR_INVALID_TABREF );
443 aEdDestArea.GrabFocus();
446 else
447 Close(); // keine Datenbereiche definiert -> Cancel
448 return 0;
452 //----------------------------------------------------------------------------
454 IMPL_LINK( ScConsolidateDlg, ClickHdl, PushButton*, pBtn )
456 if ( pBtn == &aBtnCancel )
457 Close();
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++ )
475 String aNewArea;
477 if ( ppAreas[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 );
489 delete ppAreas[i];
492 delete [] ppAreas;
494 else if ( VerifyEdit( &aEdDataArea ) )
496 String aNewArea( aEdDataArea.GetText() );
498 if ( aLbConsAreas.GetEntryPos( aNewArea ) == LISTBOX_ENTRY_NOTFOUND )
499 aLbConsAreas.InsertEntry( aNewArea );
500 else
501 INFOBOX( STR_AREA_ALREADY_INSERTED );
503 else
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();
516 return 0;
520 //----------------------------------------------------------------------------
522 IMPL_LINK( ScConsolidateDlg, SelectHdl, ListBox*, pLb )
524 if ( pLb == &aLbConsAreas )
526 if ( aLbConsAreas.GetSelectEntryCount() > 0 )
527 aBtnRemove.Enable();
528 else
529 aBtnRemove.Disable();
531 else if ( (pLb == &aLbDataArea) || (pLb == &aLbDestArea) )
533 Edit* pEd = (pLb == &aLbDataArea) ? &aEdDataArea : &aEdDestArea;
534 sal_uInt16 nSelPos = pLb->GetSelectEntryPos();
536 if ( pRangeUtil
537 && (nSelPos > 0)
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 )
551 aBtnAdd.Enable();
554 else
556 pEd->SetText( EMPTY_STRING );
557 if ( pEd == &aEdDataArea )
558 aBtnAdd.Enable();
561 return 0;
565 //----------------------------------------------------------------------------
567 IMPL_LINK( ScConsolidateDlg, ModifyHdl, formula::RefEdit*, pEd )
569 if ( pEd == &aEdDataArea )
571 String aAreaStr( pEd->GetText() );
572 if ( aAreaStr.Len() > 0 )
574 aBtnAdd.Enable();
576 else
577 aBtnAdd.Disable();
579 else if ( pEd == &aEdDestArea )
581 aLbDestArea.SelectEntryPos(0);
583 return 0;
587 //----------------------------------------------------------------------------
588 // Verallgemeinern!!! :
589 // Resource der ListBox und diese beiden Umrechnungsmethoden gibt es
590 // auch noch in tpsubt bzw. ueberall, wo StarCalc-Funktionen
591 // auswaehlbar sind.
593 ScSubTotalFunc ScConsolidateDlg::LbPosToFunc( sal_uInt16 nPos )
595 switch ( 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;
607 case 0:
608 default:
609 return SUBTOTAL_FUNC_SUM;
614 //----------------------------------------------------------------------------
616 sal_uInt16 ScConsolidateDlg::FuncToLbPos( ScSubTotalFunc eFunc )
618 switch ( 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:
632 default:
633 return 0;
637 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */