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 "scitems.hxx"
21 #include <sfx2/dispatch.hxx>
22 #include <vcl/layout.hxx>
24 #include "uiitems.hxx"
26 #include "document.hxx"
27 #include "scresid.hxx"
29 #include "reffact.hxx"
31 #include "tabopdlg.hxx"
35 ScTabOpDlg::ScTabOpDlg( SfxBindings
* pB
, SfxChildWindow
* pCW
, vcl::Window
* pParent
,
36 ScDocument
* pDocument
,
37 const ScRefAddress
& rCursorPos
)
39 : ScAnyRefDlg(pB
, pCW
, pParent
, "MultipleOperationsDialog",
40 "modules/scalc/ui/multipleoperationsdialog.ui")
41 , theFormulaCell(rCursorPos
)
43 , nCurTab(theFormulaCell
.Tab())
45 , bDlgLostFocus(false)
46 , errMsgNoFormula(ScResId(STR_NOFORMULASPECIFIED
))
47 , errMsgNoColRow(ScResId(STR_NOCOLROW
))
48 , errMsgWrongFormula(ScResId(STR_WRONGFORMULA
))
49 , errMsgWrongRowCol(ScResId(STR_WRONGROWCOL
))
50 , errMsgNoColFormula(ScResId(STR_NOCOLFORMULA
))
51 , errMsgNoRowFormula(ScResId(STR_NOROWFORMULA
))
53 get(m_pFtFormulaRange
, "formulasft");
54 get(m_pEdFormulaRange
, "formulas");
55 m_pEdFormulaRange
->SetReferences(this, m_pFtFormulaRange
);
56 get(m_pRBFormulaRange
, "formulasref");
57 m_pRBFormulaRange
->SetReferences(this, m_pEdFormulaRange
);
59 get(m_pFtRowCell
, "rowft");
60 get(m_pEdRowCell
, "row");
61 m_pEdRowCell
->SetReferences(this, m_pFtRowCell
);
62 get(m_pRBRowCell
, "rowref");
63 m_pRBRowCell
->SetReferences(this, m_pEdRowCell
);
65 get(m_pFtColCell
, "colft");
66 get(m_pEdColCell
, "col");
67 m_pEdColCell
->SetReferences(this, m_pFtColCell
);
68 get(m_pRBColCell
, "colref");
69 m_pRBColCell
->SetReferences(this, m_pEdColCell
);
72 get(m_pBtnCancel
, "cancel");
77 ScTabOpDlg::~ScTabOpDlg()
82 void ScTabOpDlg::dispose()
85 m_pFtFormulaRange
.clear();
86 m_pEdFormulaRange
.clear();
87 m_pRBFormulaRange
.clear();
97 ScAnyRefDlg::dispose();
101 void ScTabOpDlg::Init()
103 m_pBtnOk
->SetClickHdl ( LINK( this, ScTabOpDlg
, BtnHdl
) );
104 m_pBtnCancel
->SetClickHdl ( LINK( this, ScTabOpDlg
, BtnHdl
) );
106 Link
<Control
&,void> aLink
= LINK( this, ScTabOpDlg
, GetFocusHdl
);
107 m_pEdFormulaRange
->SetGetFocusHdl( aLink
);
108 m_pRBFormulaRange
->SetGetFocusHdl( aLink
);
109 m_pEdRowCell
->SetGetFocusHdl( aLink
);
110 m_pRBRowCell
->SetGetFocusHdl( aLink
);
111 m_pEdColCell
->SetGetFocusHdl( aLink
);
112 m_pRBColCell
->SetGetFocusHdl( aLink
);
114 aLink
= LINK( this, ScTabOpDlg
, LoseFocusHdl
);
115 m_pEdFormulaRange
->SetLoseFocusHdl( aLink
);
116 m_pRBFormulaRange
->SetLoseFocusHdl( aLink
);
117 m_pEdRowCell
->SetLoseFocusHdl( aLink
);
118 m_pRBRowCell
->SetLoseFocusHdl( aLink
);
119 m_pEdColCell
->SetLoseFocusHdl( aLink
);
120 m_pRBColCell
->SetLoseFocusHdl( aLink
);
122 m_pEdFormulaRange
->GrabFocus();
123 pEdActive
= m_pEdFormulaRange
;
125 //@BugID 54702 Enable/Disable only in the base class
126 //SFX_APPWINDOW->Enable();
129 bool ScTabOpDlg::Close()
131 return DoClose( ScTabOpDlgWrapper::GetChildWindowId() );
134 void ScTabOpDlg::SetActive()
138 bDlgLostFocus
= false;
140 pEdActive
->GrabFocus();
148 void ScTabOpDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
152 ScAddress::Details
aDetails(pDocP
->GetAddressConvention(), 0, 0);
154 if ( rRef
.aStart
!= rRef
.aEnd
)
155 RefInputStart(pEdActive
);
158 ScRefFlags nFmt
= ( rRef
.aStart
.Tab() == nCurTab
)
159 ? ScRefFlags::RANGE_ABS
160 : ScRefFlags::RANGE_ABS_3D
;
162 if (pEdActive
== m_pEdFormulaRange
)
164 theFormulaCell
.Set( rRef
.aStart
, false, false, false);
165 theFormulaEnd
.Set( rRef
.aEnd
, false, false, false);
166 aStr
= rRef
.Format(nFmt
, pDocP
, aDetails
);
168 else if ( pEdActive
== m_pEdRowCell
)
170 theRowCell
.Set( rRef
.aStart
, false, false, false);
171 aStr
= rRef
.aStart
.Format(nFmt
, pDocP
, aDetails
);
173 else if ( pEdActive
== m_pEdColCell
)
175 theColCell
.Set( rRef
.aStart
, false, false, false);
176 aStr
= rRef
.aStart
.Format(nFmt
, pDocP
, aDetails
);
179 pEdActive
->SetRefString( aStr
);
183 void ScTabOpDlg::RaiseError( ScTabOpErr eError
)
185 const OUString
* pMsg
= &errMsgNoFormula
;
186 Edit
* pEd
= m_pEdFormulaRange
;
190 case TABOPERR_NOFORMULA
:
191 pMsg
= &errMsgNoFormula
;
192 pEd
= m_pEdFormulaRange
;
195 case TABOPERR_NOCOLROW
:
196 pMsg
= &errMsgNoColRow
;
200 case TABOPERR_WRONGFORMULA
:
201 pMsg
= &errMsgWrongFormula
;
202 pEd
= m_pEdFormulaRange
;
205 case TABOPERR_WRONGROW
:
206 pMsg
= &errMsgWrongRowCol
;
210 case TABOPERR_NOCOLFORMULA
:
211 pMsg
= &errMsgNoColFormula
;
212 pEd
= m_pEdFormulaRange
;
215 case TABOPERR_WRONGCOL
:
216 pMsg
= &errMsgWrongRowCol
;
220 case TABOPERR_NOROWFORMULA
:
221 pMsg
= &errMsgNoRowFormula
;
222 pEd
= m_pEdFormulaRange
;
226 ScopedVclPtrInstance
<MessageDialog
>(this, *pMsg
, VCL_MESSAGE_ERROR
, VCL_BUTTONS_OK_CANCEL
)->Execute();
230 static bool lcl_Parse( const OUString
& rString
, ScDocument
* pDoc
, SCTAB nCurTab
,
231 ScRefAddress
& rStart
, ScRefAddress
& rEnd
)
234 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
235 if ( rString
.indexOf(':') != -1 )
236 bRet
= ConvertDoubleRef( pDoc
, rString
, nCurTab
, rStart
, rEnd
, eConv
);
239 bRet
= ConvertSingleRef( pDoc
, rString
, nCurTab
, rStart
, eConv
);
247 IMPL_LINK_TYPED( ScTabOpDlg
, BtnHdl
, Button
*, pBtn
, void )
249 if (pBtn
== m_pBtnOk
)
251 ScTabOpParam::Mode eMode
= ScTabOpParam::Column
;
252 sal_uInt16 nError
= 0;
254 // The following code checks:
255 // 1. do the strings contain correct cell references / defined names?
256 // 2. is formula range row if row is empty or column if column is empty
257 // or single reference if both?
258 // 3. is at least one of row or column non-empty?
260 if (m_pEdFormulaRange
->GetText().isEmpty())
261 nError
= TABOPERR_NOFORMULA
;
262 else if (m_pEdRowCell
->GetText().isEmpty() &&
263 m_pEdColCell
->GetText().isEmpty())
264 nError
= TABOPERR_NOCOLROW
;
265 else if ( !lcl_Parse( m_pEdFormulaRange
->GetText(), pDoc
, nCurTab
,
266 theFormulaCell
, theFormulaEnd
) )
267 nError
= TABOPERR_WRONGFORMULA
;
270 const formula::FormulaGrammar::AddressConvention eConv
= pDoc
->GetAddressConvention();
271 if (!m_pEdRowCell
->GetText().isEmpty())
273 if (!ConvertSingleRef( pDoc
, m_pEdRowCell
->GetText(), nCurTab
,
275 nError
= TABOPERR_WRONGROW
;
278 if (m_pEdColCell
->GetText().isEmpty() &&
279 theFormulaCell
.Col() != theFormulaEnd
.Col())
280 nError
= TABOPERR_NOCOLFORMULA
;
282 eMode
= ScTabOpParam::Row
;
285 if (!m_pEdColCell
->GetText().isEmpty())
287 if (!ConvertSingleRef( pDoc
, m_pEdColCell
->GetText(), nCurTab
,
289 nError
= TABOPERR_WRONGCOL
;
292 if (eMode
== ScTabOpParam::Row
) // both
294 eMode
= ScTabOpParam::Both
;
295 ConvertSingleRef( pDoc
, m_pEdFormulaRange
->GetText(), nCurTab
,
296 theFormulaCell
, eConv
);
298 else if (theFormulaCell
.Row() != theFormulaEnd
.Row())
299 nError
= TABOPERR_NOROWFORMULA
;
301 eMode
= ScTabOpParam::Column
;
307 RaiseError( (ScTabOpErr
) nError
);
310 ScTabOpParam
aOutParam(theFormulaCell
, theFormulaEnd
, theRowCell
, theColCell
, eMode
);
311 ScTabOpItem
aOutItem( SID_TABOP
, &aOutParam
);
313 SetDispatcherLock( false );
315 GetBindings().GetDispatcher()->ExecuteList(SID_TABOP
,
316 SfxCallMode::SLOT
| SfxCallMode::RECORD
,
321 else if (pBtn
== m_pBtnCancel
)
325 IMPL_LINK_TYPED( ScTabOpDlg
, GetFocusHdl
, Control
&, rCtrl
, void )
327 if( (&rCtrl
== static_cast<Control
*>(m_pEdFormulaRange
)) || (&rCtrl
== static_cast<Control
*>(m_pRBFormulaRange
)) )
328 pEdActive
= m_pEdFormulaRange
;
329 else if( (&rCtrl
== static_cast<Control
*>(m_pEdRowCell
)) || (&rCtrl
== static_cast<Control
*>(m_pRBRowCell
)) )
330 pEdActive
= m_pEdRowCell
;
331 else if( (&rCtrl
== static_cast<Control
*>(m_pEdColCell
)) || (&rCtrl
== static_cast<Control
*>(m_pRBColCell
)) )
332 pEdActive
= m_pEdColCell
;
337 pEdActive
->SetSelection( Selection( 0, SELECTION_MAX
) );
340 IMPL_LINK_NOARG_TYPED(ScTabOpDlg
, LoseFocusHdl
, Control
&, void)
342 bDlgLostFocus
= !IsActive();
345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */