fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / dbgui / consdlg.cxx
blob675b089032b941c234ed1b6422300a8e767440d3
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 "sc.hrc"
34 #include "consdlg.hxx"
35 #include <vcl/msgbox.hxx>
37 #define INFOBOX(id) ScopedVclPtr<InfoBox>::Create(this, ScGlobal::GetRscString(id))->Execute()
39 class ScAreaData
41 public:
42 ScAreaData()
43 : bIsDbArea(false)
47 ~ScAreaData() {}
49 void Set( const OUString& rName, const OUString& rArea, bool bDb )
51 aStrName = rName;
52 aStrArea = rArea;
53 bIsDbArea = bDb;
56 OUString aStrName;
57 OUString aStrArea;
58 bool bIsDbArea;
61 ScConsolidateDlg::ScConsolidateDlg( SfxBindings* pB, SfxChildWindow* pCW, vcl::Window* pParent,
62 const SfxItemSet& rArgSet )
64 : ScAnyRefDlg ( pB, pCW, pParent, "ConsolidateDialog" , "modules/scalc/ui/consolidatedialog.ui" ),
65 aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
66 theConsData ( static_cast<const ScConsolidateItem&>(
67 rArgSet.Get( rArgSet.GetPool()->
68 GetWhich( SID_CONSOLIDATE ) )
69 ).GetData() ),
70 rViewData ( static_cast<ScTabViewShell*>(SfxViewShell::Current())->
71 GetViewData() ),
72 pDoc ( static_cast<ScTabViewShell*>(SfxViewShell::Current())->
73 GetViewData().GetDocument() ),
74 pRangeUtil ( new ScRangeUtil ),
75 pAreaData ( NULL ),
76 nAreaDataCount ( 0 ),
77 nWhichCons ( rArgSet.GetPool()->GetWhich( SID_CONSOLIDATE ) ),
78 bDlgLostFocus ( false )
80 get(pLbFunc,"func");
81 get(pLbConsAreas,"consareas");
83 get(pLbDataArea,"lbdataarea");
84 get(pEdDataArea,"eddataarea");
85 get(pRbDataArea,"rbdataarea");
87 pRefInputEdit = pEdDataArea;
89 get(pLbDestArea,"lbdestarea");
90 get(pEdDestArea,"eddestarea");
91 get(pRbDestArea,"rbdestarea");
93 get(pExpander,"more");
94 get(pBtnByRow,"byrow");
95 get(pBtnByCol,"bycol");
96 get(pBtnRefs,"refs");
98 get(pBtnOk,"ok");
99 get(pBtnCancel,"cancel");
100 get(pBtnAdd,"add");
101 get(pBtnRemove,"delete");
103 Init();
106 ScConsolidateDlg::~ScConsolidateDlg()
108 disposeOnce();
111 void ScConsolidateDlg::dispose()
113 delete [] pAreaData;
114 delete pRangeUtil;
115 pLbFunc.clear();
116 pLbConsAreas.clear();
117 pLbDataArea.clear();
118 pEdDataArea.clear();
119 pRbDataArea.clear();
120 pLbDestArea.clear();
121 pEdDestArea.clear();
122 pRbDestArea.clear();
123 pExpander.clear();
124 pBtnByRow.clear();
125 pBtnByCol.clear();
126 pBtnRefs.clear();
127 pBtnOk.clear();
128 pBtnCancel.clear();
129 pBtnAdd.clear();
130 pBtnRemove.clear();
131 pRefInputEdit.clear();
132 ScAnyRefDlg::dispose();
135 void ScConsolidateDlg::Init()
137 OSL_ENSURE( pDoc && pRangeUtil, "Error in Ctor" );
139 OUString aStr;
140 sal_uInt16 i=0;
142 pRbDataArea->SetReferences(this, pEdDataArea);
143 pEdDataArea->SetReferences(this, get<FixedText>("ftdataarea"));
144 pRbDestArea->SetReferences(this, pEdDestArea);
145 pEdDestArea->SetReferences(this, get<FixedText>("ftdestarea"));
147 pEdDataArea ->SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
148 pEdDestArea ->SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
149 pLbDataArea ->SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
150 pLbDestArea ->SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) );
151 pEdDataArea ->SetModifyHdl ( LINK( this, ScConsolidateDlg, ModifyHdl ) );
152 pEdDestArea ->SetModifyHdl ( LINK( this, ScConsolidateDlg, ModifyHdl ) );
153 pLbConsAreas->SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) );
154 pLbDataArea ->SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) );
155 pLbDestArea ->SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) );
156 pBtnOk ->SetClickHdl ( LINK( this, ScConsolidateDlg, OkHdl ) );
157 pBtnCancel ->SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) );
158 pBtnAdd ->SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) );
159 pBtnRemove ->SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) );
161 pBtnAdd->Disable();
162 pBtnRemove->Disable();
164 pBtnByRow->Check( theConsData.bByRow );
165 pBtnByCol->Check( theConsData.bByCol );
166 pBtnRefs->Check( theConsData.bReferenceData );
168 pLbFunc->SelectEntryPos( FuncToLbPos( theConsData.eFunction ) );
170 // Hack: pLbConsAreas used to be MultiLB. We don't have VCL builder equivalent
171 // of it yet. So enable selecting multiple items here
172 pLbConsAreas->EnableMultiSelection( true );
174 pLbConsAreas->set_width_request(pLbConsAreas->approximate_char_width() * 16);
175 pLbConsAreas->SetDropDownLineCount(5);
177 // read consolidation areas
178 pLbConsAreas->Clear();
179 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
180 for ( i=0; i<theConsData.nDataAreaCount; i++ )
182 const ScArea& rArea = *(theConsData.ppDataAreas[i] );
183 if ( rArea.nTab < pDoc->GetTableCount() )
185 aStr = ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab,
186 rArea.nColEnd, rArea.nRowEnd, rArea.nTab ).Format(
187 SCR_ABS_3D, pDoc, eConv );
188 pLbConsAreas->InsertEntry( aStr );
192 if ( theConsData.nTab < pDoc->GetTableCount() )
194 aStr = ScAddress( theConsData.nCol, theConsData.nRow, theConsData.nTab
195 ).Format( SCA_ABS_3D, pDoc, eConv );
196 pEdDestArea->SetText( aStr );
198 else
199 pEdDestArea->SetText(OUString());
201 // Use the ScAreaData helper class to save those range names from the
202 // RangeNames and database ranges that appear in the ListBoxes.
204 ScRangeName* pRangeNames = pDoc->GetRangeName();
205 ScDBCollection* pDbNames = pDoc->GetDBCollection();
206 size_t nRangeCount = pRangeNames ? pRangeNames->size() : 0;
207 size_t nDbCount = pDbNames ? pDbNames->getNamedDBs().size() : 0;
209 nAreaDataCount = nRangeCount+nDbCount;
210 pAreaData = NULL;
212 if ( nAreaDataCount > 0 )
214 pAreaData = new ScAreaData[nAreaDataCount];
216 OUString aStrName;
217 sal_uInt16 nAt = 0;
218 ScRange aRange;
219 ScAreaNameIterator aIter( pDoc );
220 while ( aIter.Next( aStrName, aRange ) )
222 OUString aStrArea(aRange.Format(SCA_ABS_3D, pDoc, eConv));
223 pAreaData[nAt++].Set( aStrName, aStrArea, aIter.WasDBName() );
227 FillAreaLists();
228 ModifyHdl( pEdDestArea );
229 pLbDataArea->SelectEntryPos( 0 );
230 pEdDataArea->SetText(OUString());
231 pEdDataArea->GrabFocus();
233 //aFlSep.SetStyle( aFlSep.GetStyle() | WB_VERT );
235 //@BugID 54702 enable/disable only in base class
236 //SFX_APPWINDOW->Enable();
239 void ScConsolidateDlg::FillAreaLists()
241 pLbDataArea->Clear();
242 pLbDestArea->Clear();
243 pLbDataArea->InsertEntry( aStrUndefined );
244 pLbDestArea->InsertEntry( aStrUndefined );
246 if ( pRangeUtil && pAreaData && (nAreaDataCount > 0) )
248 for ( size_t i=0;
249 (i<nAreaDataCount) && (!pAreaData[i].aStrName.isEmpty());
250 i++ )
252 pLbDataArea->InsertEntry( pAreaData[i].aStrName, i+1 );
254 // if ( !pAreaData[i].bIsDbArea )
255 pLbDestArea->InsertEntry( pAreaData[i].aStrName, i+1 );
260 // Handover of a range within a table that has been selected by the mouse.
261 // This range is then shown in the reference window as new selection.
263 void ScConsolidateDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
265 if ( pRefInputEdit )
267 if ( rRef.aStart != rRef.aEnd )
268 RefInputStart( pRefInputEdit );
270 OUString aStr;
271 sal_uInt16 nFmt = SCR_ABS_3D; //!!! nCurTab is still missing
272 const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
274 if ( rRef.aStart.Tab() != rRef.aEnd.Tab() )
275 nFmt |= SCA_TAB2_3D;
277 if ( pRefInputEdit == pEdDataArea)
278 aStr = rRef.Format(nFmt, pDocP, eConv);
279 else if ( pRefInputEdit == pEdDestArea )
280 aStr = rRef.aStart.Format(nFmt, pDocP, eConv);
282 pRefInputEdit->SetRefString( aStr );
283 ModifyHdl( pRefInputEdit );
287 bool ScConsolidateDlg::Close()
289 return DoClose( ScConsolidateDlgWrapper::GetChildWindowId() );
292 void ScConsolidateDlg::SetActive()
294 if ( bDlgLostFocus )
296 bDlgLostFocus = false;
298 if ( pRefInputEdit )
300 pRefInputEdit->GrabFocus();
301 ModifyHdl( pRefInputEdit );
304 else
305 GrabFocus();
307 RefInputDone();
310 void ScConsolidateDlg::Deactivate()
312 bDlgLostFocus = true;
315 bool ScConsolidateDlg::VerifyEdit( formula::RefEdit* pEd )
317 if ( !pRangeUtil || !pDoc ||
318 ((pEd != pEdDataArea) && (pEd != pEdDestArea)) )
319 return false;
321 SCTAB nTab = rViewData.GetTabNo();
322 bool bEditOk = false;
323 OUString theCompleteStr;
324 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
326 if ( pEd == pEdDataArea )
328 bEditOk = ScRangeUtil::IsAbsArea( pEd->GetText(), pDoc,
329 nTab, &theCompleteStr, NULL, NULL, eConv );
331 else if ( pEd == pEdDestArea )
333 OUString aPosStr;
335 ScRangeUtil::CutPosString( pEd->GetText(), aPosStr );
336 bEditOk = ScRangeUtil::IsAbsPos( aPosStr, pDoc,
337 nTab, &theCompleteStr, NULL, eConv );
340 if ( bEditOk )
341 pEd->SetText( theCompleteStr );
343 return bEditOk;
346 // Handler:
348 IMPL_LINK( ScConsolidateDlg, GetFocusHdl, Control*, pCtr )
350 if ( pCtr ==(Control*)pEdDataArea ||
351 pCtr ==(Control*)pEdDestArea)
353 pRefInputEdit = static_cast<formula::RefEdit*>(pCtr);
355 else if(pCtr ==(Control*)pLbDataArea )
357 pRefInputEdit = pEdDataArea;
359 else if(pCtr ==(Control*)pLbDestArea )
361 pRefInputEdit = pEdDestArea;
363 return 0;
366 IMPL_LINK_NOARG(ScConsolidateDlg, OkHdl)
368 sal_uInt16 nDataAreaCount = pLbConsAreas->GetEntryCount();
370 if ( nDataAreaCount > 0 )
372 ScRefAddress aDestAddress;
373 SCTAB nTab = rViewData.GetTabNo();
374 OUString aDestPosStr( pEdDestArea->GetText() );
375 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
377 if ( ScRangeUtil::IsAbsPos( aDestPosStr, pDoc, nTab, NULL, &aDestAddress, eConv ) )
379 ScConsolidateParam theOutParam( theConsData );
380 ScArea** ppDataAreas = new ScArea*[nDataAreaCount];
381 ScArea* pArea;
382 sal_uInt16 i=0;
384 for ( i=0; i<nDataAreaCount; i++ )
386 pArea = new ScArea;
387 ScRangeUtil::MakeArea( pLbConsAreas->GetEntry( i ),
388 *pArea, pDoc, nTab, eConv );
389 ppDataAreas[i] = pArea;
392 theOutParam.nCol = aDestAddress.Col();
393 theOutParam.nRow = aDestAddress.Row();
394 theOutParam.nTab = aDestAddress.Tab();
395 theOutParam.eFunction = LbPosToFunc( pLbFunc->GetSelectEntryPos() );
396 theOutParam.bByCol = pBtnByCol->IsChecked();
397 theOutParam.bByRow = pBtnByRow->IsChecked();
398 theOutParam.bReferenceData = pBtnRefs->IsChecked();
399 theOutParam.SetAreas( ppDataAreas, nDataAreaCount );
401 for ( i=0; i<nDataAreaCount; i++ )
402 delete ppDataAreas[i];
403 delete [] ppDataAreas;
405 ScConsolidateItem aOutItem( nWhichCons, &theOutParam );
407 SetDispatcherLock( false );
408 SwitchToDocument();
409 GetBindings().GetDispatcher()->Execute( SID_CONSOLIDATE,
410 SfxCallMode::SLOT | SfxCallMode::RECORD,
411 &aOutItem, 0L, 0L );
412 Close();
414 else
416 INFOBOX( STR_INVALID_TABREF );
417 pEdDestArea->GrabFocus();
420 else
421 Close(); // no area defined -> Cancel
422 return 0;
425 IMPL_LINK( ScConsolidateDlg, ClickHdl, PushButton*, pBtn )
427 if ( pBtn == pBtnCancel )
428 Close();
429 else if ( pBtn == pBtnAdd )
431 if ( !pEdDataArea->GetText().isEmpty() )
433 OUString aNewEntry( pEdDataArea->GetText() );
434 ScArea** ppAreas = NULL;
435 sal_uInt16 nAreaCount = 0;
436 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
438 if ( ScRangeUtil::IsAbsTabArea( aNewEntry, pDoc, &ppAreas, &nAreaCount, true, eConv ) )
440 // IsAbsTabArea() creates an array of ScArea pointers,
441 // which have been created dynamically as well.
442 // These objects need to be deleted here.
444 for ( sal_uInt16 i=0; i<nAreaCount; i++ )
446 OUString aNewArea;
448 if ( ppAreas[i] )
450 const ScArea& rArea = *(ppAreas[i]);
451 aNewArea = ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab,
452 rArea.nColEnd, rArea.nRowEnd, rArea.nTab
453 ).Format(SCR_ABS_3D, pDoc, eConv);
455 if ( pLbConsAreas->GetEntryPos( aNewArea )
456 == LISTBOX_ENTRY_NOTFOUND )
458 pLbConsAreas->InsertEntry( aNewArea );
460 delete ppAreas[i];
463 delete [] ppAreas;
465 else if ( VerifyEdit( pEdDataArea ) )
467 OUString aNewArea( pEdDataArea->GetText() );
469 if ( pLbConsAreas->GetEntryPos( aNewArea ) == LISTBOX_ENTRY_NOTFOUND )
470 pLbConsAreas->InsertEntry( aNewArea );
471 else
472 INFOBOX( STR_AREA_ALREADY_INSERTED );
474 else
476 INFOBOX( STR_INVALID_TABREF );
477 pEdDataArea->GrabFocus();
481 else if ( pBtn == pBtnRemove )
483 while ( pLbConsAreas->GetSelectEntryCount() )
484 pLbConsAreas->RemoveEntry( pLbConsAreas->GetSelectEntryPos() );
485 pBtnRemove->Disable();
487 return 0;
490 IMPL_LINK( ScConsolidateDlg, SelectHdl, ListBox*, pLb )
492 if ( pLb == pLbConsAreas )
494 if ( pLbConsAreas->GetSelectEntryCount() > 0 )
495 pBtnRemove->Enable();
496 else
497 pBtnRemove->Disable();
499 else if ( (pLb == pLbDataArea) || (pLb == pLbDestArea) )
501 Edit* pEd = (pLb == pLbDataArea) ? pEdDataArea : pEdDestArea;
502 sal_uInt16 nSelPos = pLb->GetSelectEntryPos();
504 if ( pRangeUtil
505 && (nSelPos > 0)
506 && (nAreaDataCount > 0)
507 && (pAreaData != NULL) )
509 if ( static_cast<size_t>(nSelPos) <= nAreaDataCount )
511 OUString aString( pAreaData[nSelPos-1].aStrArea );
513 if ( pLb == pLbDestArea )
514 ScRangeUtil::CutPosString( aString, aString );
516 pEd->SetText( aString );
518 if ( pEd == pEdDataArea )
519 pBtnAdd->Enable();
522 else
524 pEd->SetText( EMPTY_OUSTRING );
525 if ( pEd == pEdDataArea )
526 pBtnAdd->Enable();
529 return 0;
532 IMPL_LINK( ScConsolidateDlg, ModifyHdl, formula::RefEdit*, pEd )
534 if ( pEd == pEdDataArea )
536 OUString aAreaStr( pEd->GetText() );
537 if ( !aAreaStr.isEmpty() )
539 pBtnAdd->Enable();
541 else
542 pBtnAdd->Disable();
544 else if ( pEd == pEdDestArea )
546 pLbDestArea->SelectEntryPos(0);
548 return 0;
551 // TODO: generalize!
552 // Resource of the ListBox and these two conversion methods are also in
553 // tpsubt and everywhere, where StarCalc functions are selectable.
555 ScSubTotalFunc ScConsolidateDlg::LbPosToFunc( sal_uInt16 nPos )
557 switch ( nPos )
559 case 2: return SUBTOTAL_FUNC_AVE;
560 case 6: return SUBTOTAL_FUNC_CNT;
561 case 1: return SUBTOTAL_FUNC_CNT2;
562 case 3: return SUBTOTAL_FUNC_MAX;
563 case 4: return SUBTOTAL_FUNC_MIN;
564 case 5: return SUBTOTAL_FUNC_PROD;
565 case 7: return SUBTOTAL_FUNC_STD;
566 case 8: return SUBTOTAL_FUNC_STDP;
567 case 9: return SUBTOTAL_FUNC_VAR;
568 case 10: return SUBTOTAL_FUNC_VARP;
569 case 0:
570 default:
571 return SUBTOTAL_FUNC_SUM;
575 sal_uInt16 ScConsolidateDlg::FuncToLbPos( ScSubTotalFunc eFunc )
577 switch ( eFunc )
579 case SUBTOTAL_FUNC_AVE: return 2;
580 case SUBTOTAL_FUNC_CNT: return 6;
581 case SUBTOTAL_FUNC_CNT2: return 1;
582 case SUBTOTAL_FUNC_MAX: return 3;
583 case SUBTOTAL_FUNC_MIN: return 4;
584 case SUBTOTAL_FUNC_PROD: return 5;
585 case SUBTOTAL_FUNC_STD: return 7;
586 case SUBTOTAL_FUNC_STDP: return 8;
587 case SUBTOTAL_FUNC_VAR: return 9;
588 case SUBTOTAL_FUNC_VARP: return 10;
589 case SUBTOTAL_FUNC_NONE:
590 case SUBTOTAL_FUNC_SUM:
591 default:
592 return 0;
596 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */