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