xref: /trunk/main/sc/source/ui/miscdlgs/tabopdlg.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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