xref: /AOO41X/main/sc/source/ui/miscdlgs/tabopdlg.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 
33 //----------------------------------------------------------------------------
34 
35 #include "scitems.hxx"
36 #include <sfx2/dispatch.hxx>
37 #include <vcl/msgbox.hxx>
38 
39 #include "uiitems.hxx"
40 #include "global.hxx"
41 #include "document.hxx"
42 #include "scresid.hxx"
43 #include "sc.hrc"
44 #include "reffact.hxx"
45 #include "tabopdlg.hrc"
46 
47 #define _TABOPDLG_CXX
48 #include "tabopdlg.hxx"
49 
50 
51 //============================================================================
52 //	class ScTabOpDlg
53 //----------------------------------------------------------------------------
54 
55 ScTabOpDlg::ScTabOpDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
56 						ScDocument*         pDocument,
57 						const ScRefAddress&	rCursorPos )
58 
59 	:	ScAnyRefDlg			( pB, pCW, pParent, RID_SCDLG_TABOP ),
60 		//
61         aFlVariables        ( this, ScResId( FL_VARIABLES ) ),
62 		aFtFormulaRange     ( this, ScResId( FT_FORMULARANGE ) ),
63         aEdFormulaRange     ( this, this, ScResId( ED_FORMULARANGE ) ),
64 		aRBFormulaRange		( this, ScResId( RB_FORMULARANGE ), &aEdFormulaRange, this ),
65 		aFtRowCell       	( this, ScResId( FT_ROWCELL ) ),
66         aEdRowCell          ( this, this, ScResId( ED_ROWCELL ) ),
67 		aRBRowCell			( this, ScResId( RB_ROWCELL ), &aEdRowCell, this ),
68 		aFtColCell       	( this, ScResId( FT_COLCELL ) ),
69         aEdColCell          ( this, this, ScResId( ED_COLCELL ) ),
70 		aRBColCell			( this, ScResId( RB_COLCELL ), &aEdColCell, this ),
71 		aBtnOk              ( this, ScResId( BTN_OK ) ),
72 		aBtnCancel          ( this, ScResId( BTN_CANCEL ) ),
73 		aBtnHelp            ( this, ScResId( BTN_HELP ) ),
74 		//
75 		theFormulaCell      ( rCursorPos ),
76 		pDoc                ( pDocument ),
77 		nCurTab             ( theFormulaCell.Tab() ),
78 		pEdActive           ( NULL ),
79 		bDlgLostFocus       ( sal_False ),
80 		errMsgNoFormula		( ScResId( STR_NOFORMULA ) ),
81 		errMsgNoColRow		( ScResId( STR_NOCOLROW ) ),
82 		errMsgWrongFormula	( ScResId( STR_WRONGFORMULA ) ),
83 		errMsgWrongRowCol	( ScResId( STR_WRONGROWCOL ) ),
84 		errMsgNoColFormula	( ScResId( STR_NOCOLFORMULA ) ),
85 		errMsgNoRowFormula	( ScResId( STR_NOROWFORMULA ) )
86 {
87 	Init();
88 	FreeResource();
89 }
90 
91 //----------------------------------------------------------------------------
92 
93 __EXPORT ScTabOpDlg::~ScTabOpDlg()
94 {
95 	Hide();
96 }
97 
98 //----------------------------------------------------------------------------
99 
100 void __EXPORT ScTabOpDlg::Init()
101 {
102 	aBtnOk.			SetClickHdl		( LINK( this, ScTabOpDlg, BtnHdl ) );
103 	aBtnCancel.		SetClickHdl		( LINK( this, ScTabOpDlg, BtnHdl ) );
104 
105     Link aLink = LINK( this, ScTabOpDlg, GetFocusHdl );
106     aEdFormulaRange.SetGetFocusHdl( aLink );
107     aRBFormulaRange.SetGetFocusHdl( aLink );
108     aEdRowCell.     SetGetFocusHdl( aLink );
109     aRBRowCell.     SetGetFocusHdl( aLink );
110     aEdColCell.     SetGetFocusHdl( aLink );
111     aRBColCell.     SetGetFocusHdl( aLink );
112 
113     aLink = LINK( this, ScTabOpDlg, LoseFocusHdl );
114     aEdFormulaRange.SetLoseFocusHdl( aLink );
115     aRBFormulaRange.SetLoseFocusHdl( aLink );
116     aEdRowCell.     SetLoseFocusHdl( aLink );
117     aRBRowCell.     SetLoseFocusHdl( aLink );
118     aEdColCell.     SetLoseFocusHdl( aLink );
119     aRBColCell.     SetLoseFocusHdl( aLink );
120 
121 	aEdFormulaRange.GrabFocus();
122 	pEdActive = &aEdFormulaRange;
123 
124 	//@BugID 54702 Enablen/Disablen nur noch in Basisklasse
125 	//SFX_APPWINDOW->Enable();
126 }
127 
128 //----------------------------------------------------------------------------
129 
130 sal_Bool __EXPORT ScTabOpDlg::Close()
131 {
132 	return DoClose( ScTabOpDlgWrapper::GetChildWindowId() );
133 }
134 
135 //----------------------------------------------------------------------------
136 
137 void ScTabOpDlg::SetActive()
138 {
139 	if ( bDlgLostFocus )
140 	{
141 		bDlgLostFocus = sal_False;
142         if( pEdActive )
143             pEdActive->GrabFocus();
144 	}
145 	else
146 		GrabFocus();
147 
148 	RefInputDone();
149 }
150 
151 //----------------------------------------------------------------------------
152 
153 void ScTabOpDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
154 {
155 	if ( pEdActive )
156 	{
157         ScAddress::Details aDetails(pDocP->GetAddressConvention(), 0, 0);
158 
159 		if ( rRef.aStart != rRef.aEnd )
160 			RefInputStart(pEdActive);
161 
162 		String		aStr;
163 		sal_uInt16	 	nFmt = ( rRef.aStart.Tab() == nCurTab )
164 								? SCR_ABS
165 								: SCR_ABS_3D;
166 
167 		if ( pEdActive == &aEdFormulaRange )
168 		{
169 			theFormulaCell.Set( rRef.aStart, false, false, false);
170 			theFormulaEnd.Set( rRef.aEnd, false, false, false);
171             rRef.Format( aStr, nFmt, pDocP, aDetails );
172 		}
173 		else if ( pEdActive == &aEdRowCell )
174 		{
175 			theRowCell.Set( rRef.aStart, false, false, false);
176             rRef.aStart.Format( aStr, nFmt, pDocP, aDetails );
177 		}
178 		else if ( pEdActive == &aEdColCell )
179 		{
180 			theColCell.Set( rRef.aStart, false, false, false);
181             rRef.aStart.Format( aStr, nFmt, pDocP, aDetails );
182 		}
183 
184 		pEdActive->SetRefString( aStr );
185 	}
186 }
187 
188 //----------------------------------------------------------------------------
189 
190 void ScTabOpDlg::RaiseError( ScTabOpErr eError )
191 {
192 	const String* pMsg = &errMsgNoFormula;
193 	Edit*		  pEd  = &aEdFormulaRange;
194 
195 	switch ( eError )
196 	{
197 		case TABOPERR_NOFORMULA:
198 			pMsg = &errMsgNoFormula;
199 			pEd  = &aEdFormulaRange;
200 			break;
201 
202 		case TABOPERR_NOCOLROW:
203 			pMsg = &errMsgNoColRow;
204 			pEd  = &aEdRowCell;
205 			break;
206 
207 		case TABOPERR_WRONGFORMULA:
208 			pMsg = &errMsgWrongFormula;
209 			pEd  = &aEdFormulaRange;
210 			break;
211 
212 		case TABOPERR_WRONGROW:
213 			pMsg = &errMsgWrongRowCol;
214 			pEd  = &aEdRowCell;
215 			break;
216 
217 		case TABOPERR_NOCOLFORMULA:
218 			pMsg = &errMsgNoColFormula;
219 			pEd  = &aEdFormulaRange;
220 			break;
221 
222 		case TABOPERR_WRONGCOL:
223 			pMsg = &errMsgWrongRowCol;
224 			pEd  = &aEdColCell;
225 			break;
226 
227 		case TABOPERR_NOROWFORMULA:
228 			pMsg = &errMsgNoRowFormula;
229 			pEd  = &aEdFormulaRange;
230 			break;
231 	}
232 
233 	ErrorBox( this, WinBits( WB_OK_CANCEL | WB_DEF_OK), *pMsg ).Execute();
234 	pEd->GrabFocus();
235 }
236 
237 //----------------------------------------------------------------------------
238 
239 sal_Bool lcl_Parse( const String& rString, ScDocument* pDoc, SCTAB nCurTab,
240 				ScRefAddress& rStart, ScRefAddress& rEnd )
241 {
242 	sal_Bool bRet = sal_False;
243     const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
244 	if ( rString.Search(':') != STRING_NOTFOUND )
245 		bRet = ConvertDoubleRef( pDoc, rString, nCurTab, rStart, rEnd, eConv );
246 	else
247 	{
248 		bRet = ConvertSingleRef( pDoc, rString, nCurTab, rStart, eConv );
249 		rEnd = rStart;
250 	}
251 	return bRet;
252 }
253 
254 //----------------------------------------------------------------------------
255 // Handler:
256 
257 IMPL_LINK( ScTabOpDlg, BtnHdl, PushButton*, pBtn )
258 {
259 	if ( pBtn == &aBtnOk )
260 	{
261 		sal_uInt8 nMode = 3;
262 		sal_uInt16 nError = 0;
263 
264 		// Zu ueberpruefen:
265 		// 1. enthalten die Strings korrekte Tabellenkoordinaten/def.Namen?
266 		// 2. IstFormelRang Zeile bei leerer Zeile bzw. Spalte bei leerer Spalte
267 		//    bzw. Einfachreferenz bei beidem?
268 		// 3. Ist mindestens Zeile oder Spalte und Formel voll?
269 
270 		if (aEdFormulaRange.GetText().Len() == 0)
271 			nError = TABOPERR_NOFORMULA;
272 		else if (aEdRowCell.GetText().Len() == 0 &&
273 				 aEdColCell.GetText().Len() == 0)
274 			nError = TABOPERR_NOCOLROW;
275 		else if ( !lcl_Parse( aEdFormulaRange.GetText(), pDoc, nCurTab,
276 								theFormulaCell, theFormulaEnd ) )
277 			nError = TABOPERR_WRONGFORMULA;
278 		else
279 		{
280             const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
281 			if (aEdRowCell.GetText().Len() > 0)
282 			{
283 				if (!ConvertSingleRef( pDoc, aEdRowCell.GetText(), nCurTab,
284                                        theRowCell, eConv ))
285 					nError = TABOPERR_WRONGROW;
286 				else
287 				{
288 					if (aEdColCell.GetText().Len() == 0 &&
289 						theFormulaCell.Col() != theFormulaEnd.Col())
290 						nError = TABOPERR_NOCOLFORMULA;
291 					else
292 						nMode = 1;
293 				}
294 			}
295 			if (aEdColCell.GetText().Len() > 0)
296 			{
297 				if (!ConvertSingleRef( pDoc, aEdColCell.GetText(), nCurTab,
298 									   theColCell, eConv ))
299 					nError = TABOPERR_WRONGCOL;
300 				else
301 				{
302 					if (nMode == 1)							// beides
303 					{
304 						nMode = 2;
305 						ConvertSingleRef( pDoc, aEdFormulaRange.GetText(), nCurTab,
306 										  theFormulaCell, eConv );
307 					}
308 					else if (theFormulaCell.Row() != theFormulaEnd.Row())
309 						nError = TABOPERR_NOROWFORMULA;
310 					else
311 						nMode = 0;
312 				}
313 			}
314 		}
315 
316 		if (nError)
317 			RaiseError( (ScTabOpErr) nError );
318 		else
319 		{
320 			ScTabOpParam aOutParam( theFormulaCell,
321 									theFormulaEnd,
322 									theRowCell,
323 									theColCell,
324 									nMode );
325 			ScTabOpItem	 aOutItem( SID_TABOP, &aOutParam );
326 
327 			SetDispatcherLock( sal_False );
328 			SwitchToDocument();
329 			GetBindings().GetDispatcher()->Execute( SID_TABOP,
330 									  SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
331 									  &aOutItem, 0L, 0L );
332 			Close();
333 		}
334 	}
335 	else if ( pBtn == &aBtnCancel )
336 		Close();
337 
338 	return 0;
339 }
340 
341 //----------------------------------------------------------------------------
342 
343 IMPL_LINK( ScTabOpDlg, GetFocusHdl, Control*, pCtrl )
344 {
345     if( (pCtrl == (Control*)&aEdFormulaRange) || (pCtrl == (Control*)&aRBFormulaRange) )
346         pEdActive = &aEdFormulaRange;
347     else if( (pCtrl == (Control*)&aEdRowCell) || (pCtrl == (Control*)&aRBRowCell) )
348         pEdActive = &aEdRowCell;
349     else if( (pCtrl == (Control*)&aEdColCell) || (pCtrl == (Control*)&aRBColCell) )
350         pEdActive = &aEdColCell;
351     else
352         pEdActive = NULL;
353 
354     if( pEdActive )
355         pEdActive->SetSelection( Selection( 0, SELECTION_MAX ) );
356 
357 	return 0;
358 }
359 
360 //----------------------------------------------------------------------------
361 
362 IMPL_LINK( ScTabOpDlg, LoseFocusHdl, Control*, EMPTYARG )
363 {
364 	bDlgLostFocus = !IsActive();
365 	return 0;
366 }
367 
368 
369 
370 
371 
372