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 // INCLUDE --------------------------------------------------------------- 34 35 #ifdef _MSC_VER 36 #pragma optimize ("", off) 37 #endif 38 39 #include <sfx2/bindings.hxx> 40 #include <sfx2/viewfrm.hxx> 41 #include <svl/aeitem.hxx> 42 #include <svl/whiter.hxx> 43 #include <unotools/moduleoptions.hxx> 44 #include <svl/languageoptions.hxx> 45 #include <sfx2/dispatch.hxx> 46 47 #include "tabvwsh.hxx" 48 #include "drawattr.hxx" 49 #include "drawsh.hxx" 50 #include "drawview.hxx" 51 #include "fupoor.hxx" 52 #include "fuconrec.hxx" 53 #include "fuconpol.hxx" 54 #include "fuconarc.hxx" 55 #include "fuconuno.hxx" 56 #include "fusel.hxx" 57 #include "futext.hxx" 58 #include "fumark.hxx" 59 #include "fuinsert.hxx" 60 #include "global.hxx" 61 #include "sc.hrc" 62 #include "scmod.hxx" 63 #include "appoptio.hxx" 64 65 // #98185# Create default drawing objects via keyboard 66 #include <svx/svdpagv.hxx> 67 #include <svl/stritem.hxx> 68 #include <svx/svdpage.hxx> 69 #include <fuconcustomshape.hxx> 70 71 // ----------------------------------------------------------------------- 72 73 SdrView* __EXPORT ScTabViewShell::GetDrawView() const 74 { 75 return ((ScTabViewShell*)this)->GetScDrawView(); // GetScDrawView ist nicht-const 76 } 77 78 void ScTabViewShell::WindowChanged() 79 { 80 Window* pWin = GetActiveWin(); 81 82 ScDrawView* pDrView = GetScDrawView(); 83 if (pDrView) 84 pDrView->SetActualWin(pWin); 85 86 FuPoor* pFunc = GetDrawFuncPtr(); 87 if (pFunc) 88 pFunc->SetWindow(pWin); 89 90 // when font from InputContext is used, 91 // this must be moved to change of cursor position: 92 UpdateInputContext(); 93 } 94 95 void ScTabViewShell::ExecDraw(SfxRequest& rReq) 96 { 97 SC_MOD()->InputEnterHandler(); 98 UpdateInputHandler(); 99 100 MakeDrawLayer(); 101 102 ScTabView* pTabView = GetViewData()->GetView(); 103 SfxBindings& rBindings = GetViewFrame()->GetBindings(); 104 105 Window* pWin = pTabView->GetActiveWin(); 106 ScDrawView* pView = pTabView->GetScDrawView(); 107 SdrModel* pDoc = pView->GetModel(); 108 109 const SfxItemSet *pArgs = rReq.GetArgs(); 110 sal_uInt16 nNewId = rReq.GetSlot(); 111 112 if ( nNewId == SID_DRAW_CHART ) 113 { 114 // #i71254# directly insert a chart instead of drawing its output rectangle 115 FuInsertChart(this, pWin, pView, pDoc, rReq); 116 return; 117 } 118 119 // 120 // Pseudo-Slots von Draw-Toolbox auswerten 121 //! wird das ueberhaupt noch gebraucht ????? 122 // 123 124 if (nNewId == SID_INSERT_DRAW && pArgs) 125 { 126 const SfxPoolItem* pItem; 127 if ( pArgs->GetItemState( SID_INSERT_DRAW, sal_True, &pItem ) == SFX_ITEM_SET && 128 pItem->ISA( SvxDrawToolItem ) ) 129 { 130 SvxDrawToolEnum eSel = (SvxDrawToolEnum)((const SvxDrawToolItem*)pItem)->GetValue(); 131 switch (eSel) 132 { 133 case SVX_SNAP_DRAW_SELECT: nNewId = SID_OBJECT_SELECT; break; 134 case SVX_SNAP_DRAW_LINE: nNewId = SID_DRAW_LINE; break; 135 case SVX_SNAP_DRAW_RECT: nNewId = SID_DRAW_RECT; break; 136 case SVX_SNAP_DRAW_ELLIPSE: nNewId = SID_DRAW_ELLIPSE; break; 137 case SVX_SNAP_DRAW_POLYGON_NOFILL: nNewId = SID_DRAW_POLYGON_NOFILL; break; 138 case SVX_SNAP_DRAW_BEZIER_NOFILL: nNewId = SID_DRAW_BEZIER_NOFILL; break; 139 case SVX_SNAP_DRAW_FREELINE_NOFILL: nNewId = SID_DRAW_FREELINE_NOFILL; break; 140 case SVX_SNAP_DRAW_ARC: nNewId = SID_DRAW_ARC; break; 141 case SVX_SNAP_DRAW_PIE: nNewId = SID_DRAW_PIE; break; 142 case SVX_SNAP_DRAW_CIRCLECUT: nNewId = SID_DRAW_CIRCLECUT; break; 143 case SVX_SNAP_DRAW_TEXT: nNewId = SID_DRAW_TEXT; break; 144 case SVX_SNAP_DRAW_TEXT_VERTICAL: nNewId = SID_DRAW_TEXT_VERTICAL; break; 145 case SVX_SNAP_DRAW_TEXT_MARQUEE: nNewId = SID_DRAW_TEXT_MARQUEE; break; 146 case SVX_SNAP_DRAW_CAPTION: nNewId = SID_DRAW_CAPTION; break; 147 case SVX_SNAP_DRAW_CAPTION_VERTICAL: nNewId = SID_DRAW_CAPTION_VERTICAL; break; 148 } 149 } 150 else // sal_uInt16-Item vom Controller 151 { 152 rReq.Done(); 153 return; 154 } 155 } 156 157 if ( nNewId == SID_DRAW_SELECT ) 158 nNewId = SID_OBJECT_SELECT; 159 160 sal_uInt16 nNewFormId = 0; 161 if ( nNewId == SID_FM_CREATE_CONTROL && pArgs ) 162 { 163 const SfxPoolItem* pItem; 164 if ( pArgs->GetItemState( SID_FM_CONTROL_IDENTIFIER, sal_True, &pItem ) == SFX_ITEM_SET && 165 pItem->ISA( SfxUInt16Item ) ) 166 nNewFormId = ((const SfxUInt16Item*)pItem)->GetValue(); 167 } 168 169 String sStringItemValue; 170 if ( pArgs ) 171 { 172 const SfxPoolItem* pItem; 173 if ( pArgs->GetItemState( nNewId, sal_True, &pItem ) == SFX_ITEM_SET && pItem->ISA( SfxStringItem ) ) 174 sStringItemValue = static_cast<const SfxStringItem*>(pItem)->GetValue(); 175 } 176 bool bSwitchCustom = ( sStringItemValue.Len() && sDrawCustom.Len() && sStringItemValue != sDrawCustom ); 177 178 if (nNewId == SID_INSERT_FRAME) // vom Tbx-Button 179 nNewId = SID_DRAW_TEXT; 180 181 // #97016# CTRL-SID_OBJECT_SELECT is used to select the first object, 182 // but not if SID_OBJECT_SELECT is the result of clicking a create function again, 183 // so this must be tested before changing nNewId below. 184 sal_Bool bSelectFirst = ( nNewId == SID_OBJECT_SELECT && (rReq.GetModifier() & KEY_MOD1) ); 185 186 sal_Bool bEx = IsDrawSelMode(); 187 if ( rReq.GetModifier() & KEY_MOD1 ) 188 { 189 // #97016# always allow keyboard selection also on background layer 190 // #98185# also allow creation of default objects if the same object type 191 // was already active 192 bEx = sal_True; 193 } 194 else if ( nNewId == nDrawSfxId && ( nNewId != SID_FM_CREATE_CONTROL || 195 nNewFormId == nFormSfxId || nNewFormId == 0 ) && !bSwitchCustom ) 196 { 197 // #i52871# if a different custom shape is selected, the slot id can be the same, 198 // so the custom shape type string has to be compared, too. 199 200 // SID_FM_CREATE_CONTROL mit nNewFormId==0 (ohne Parameter) kommt beim Deaktivieren 201 // aus FuConstruct::SimpleMouseButtonUp 202 // #59280# Execute fuer die Form-Shell, um im Controller zu deselektieren 203 if ( nNewId == SID_FM_CREATE_CONTROL ) 204 { 205 GetViewData()->GetDispatcher().Execute(SID_FM_LEAVE_CREATE); 206 GetViewFrame()->GetBindings().InvalidateAll(sal_False); 207 //! was fuer einen Slot braucht der komische Controller wirklich, um das anzuzeigen???? 208 } 209 210 bEx = !bEx; 211 nNewId = SID_OBJECT_SELECT; 212 } 213 else 214 bEx = sal_True; 215 216 if ( nDrawSfxId == SID_FM_CREATE_CONTROL && nNewId != nDrawSfxId ) 217 { 218 // Wechsel von Control- zu Zeichenfunktion -> im Control-Controller deselektieren 219 GetViewData()->GetDispatcher().Execute(SID_FM_LEAVE_CREATE); 220 GetViewFrame()->GetBindings().InvalidateAll(sal_False); 221 //! was fuer einen Slot braucht der komische Controller wirklich, um das anzuzeigen???? 222 } 223 224 SetDrawSelMode(bEx); 225 226 pView->LockBackgroundLayer( !bEx ); 227 228 if ( bSelectFirst ) 229 { 230 // #97016# select first draw object if none is selected yet 231 if(!pView->AreObjectsMarked()) 232 { 233 // select first object 234 pView->UnmarkAllObj(); 235 pView->MarkNextObj(sal_True); 236 237 // ...and make it visible 238 if(pView->AreObjectsMarked()) 239 pView->MakeVisible(pView->GetAllMarkedRect(), *pWin); 240 } 241 } 242 243 nDrawSfxId = nNewId; 244 sDrawCustom.Erase(); // value is set below for custom shapes 245 246 if ( nNewId != SID_DRAW_CHART ) // Chart nicht mit DrawShell 247 { 248 if ( nNewId == SID_DRAW_TEXT || nNewId == SID_DRAW_TEXT_VERTICAL || 249 nNewId == SID_DRAW_TEXT_MARQUEE || nNewId == SID_DRAW_NOTEEDIT ) 250 SetDrawTextShell( sal_True ); 251 else 252 { 253 if ( bEx || pView->GetMarkedObjectList().GetMarkCount() != 0 ) 254 SetDrawShellOrSub(); 255 else 256 SetDrawShell( sal_False ); 257 } 258 } 259 260 if (pTabView->GetDrawFuncPtr()) 261 { 262 if (pTabView->GetDrawFuncOldPtr() != pTabView->GetDrawFuncPtr()) 263 delete pTabView->GetDrawFuncOldPtr(); 264 265 pTabView->GetDrawFuncPtr()->Deactivate(); 266 pTabView->SetDrawFuncOldPtr(pTabView->GetDrawFuncPtr()); 267 pTabView->SetDrawFuncPtr(NULL); 268 } 269 270 SfxRequest aNewReq(rReq); 271 aNewReq.SetSlot(nDrawSfxId); 272 273 switch (nNewId) 274 { 275 case SID_OBJECT_SELECT: 276 //@#70206# Nicht immer zurueckschalten 277 if(pView->GetMarkedObjectList().GetMarkCount() == 0) SetDrawShell(bEx); 278 pTabView->SetDrawFuncPtr(new FuSelection(this, pWin, pView, pDoc, aNewReq)); 279 break; 280 281 case SID_DRAW_LINE: 282 case SID_DRAW_RECT: 283 case SID_DRAW_ELLIPSE: 284 pTabView->SetDrawFuncPtr(new FuConstRectangle(this, pWin, pView, pDoc, aNewReq)); 285 break; 286 287 case SID_DRAW_CAPTION: 288 case SID_DRAW_CAPTION_VERTICAL: 289 pTabView->SetDrawFuncPtr(new FuConstRectangle(this, pWin, pView, pDoc, aNewReq)); 290 pView->SetFrameDragSingles( sal_False ); 291 rBindings.Invalidate( SID_BEZIER_EDIT ); 292 break; 293 294 case SID_DRAW_POLYGON: 295 case SID_DRAW_POLYGON_NOFILL: 296 case SID_DRAW_BEZIER_NOFILL: 297 case SID_DRAW_FREELINE_NOFILL: 298 pTabView->SetDrawFuncPtr(new FuConstPolygon(this, pWin, pView, pDoc, aNewReq)); 299 break; 300 301 case SID_DRAW_ARC: 302 case SID_DRAW_PIE: 303 case SID_DRAW_CIRCLECUT: 304 pTabView->SetDrawFuncPtr(new FuConstArc(this, pWin, pView, pDoc, aNewReq)); 305 break; 306 307 case SID_DRAW_TEXT: 308 case SID_DRAW_TEXT_VERTICAL: 309 case SID_DRAW_TEXT_MARQUEE: 310 case SID_DRAW_NOTEEDIT: 311 pTabView->SetDrawFuncPtr(new FuText(this, pWin, pView, pDoc, aNewReq)); 312 break; 313 314 case SID_FM_CREATE_CONTROL: 315 SetDrawFormShell(sal_True); 316 pTabView->SetDrawFuncPtr(new FuConstUnoControl(this, pWin, pView, pDoc, aNewReq)); 317 nFormSfxId = nNewFormId; 318 break; 319 320 case SID_DRAW_CHART: 321 //UNUSED2008-05 bChartDlgIsEdit = sal_False; 322 pTabView->SetDrawFuncPtr(new FuMarkRect(this, pWin, pView, pDoc, aNewReq)); 323 break; 324 325 case SID_DRAWTBX_CS_BASIC : 326 case SID_DRAWTBX_CS_SYMBOL : 327 case SID_DRAWTBX_CS_ARROW : 328 case SID_DRAWTBX_CS_FLOWCHART : 329 case SID_DRAWTBX_CS_CALLOUT : 330 case SID_DRAWTBX_CS_STAR : 331 case SID_DRAW_CS_ID : 332 { 333 pTabView->SetDrawFuncPtr( new FuConstCustomShape( this, pWin, pView, pDoc, aNewReq )); 334 if ( nNewId != SID_DRAW_CS_ID ) 335 { 336 SFX_REQUEST_ARG( rReq, pEnumCommand, SfxStringItem, nNewId, sal_False ); 337 if ( pEnumCommand ) 338 { 339 aCurrShapeEnumCommand[ nNewId - SID_DRAWTBX_CS_BASIC ] = pEnumCommand->GetValue(); 340 SfxBindings& rBind = GetViewFrame()->GetBindings(); 341 rBind.Invalidate( nNewId ); 342 rBind.Update( nNewId ); 343 344 sDrawCustom = pEnumCommand->GetValue(); // to detect when a different shape type is selected 345 } 346 } 347 } 348 break; 349 350 default: 351 break; 352 } 353 354 if (pTabView->GetDrawFuncPtr()) 355 pTabView->GetDrawFuncPtr()->Activate(); 356 357 rReq.Done(); 358 359 rBindings.Invalidate( SID_INSERT_DRAW ); 360 rBindings.Update( SID_INSERT_DRAW ); 361 362 // #98185# Create default drawing objects via keyboard 363 // with qualifier construct directly 364 FuPoor* pFuActual = GetDrawFuncPtr(); 365 366 if(pFuActual && (rReq.GetModifier() & KEY_MOD1)) 367 { 368 // #98185# Create default drawing objects via keyboard 369 const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions(); 370 sal_uInt32 nDefaultObjectSizeWidth = rAppOpt.GetDefaultObjectSizeWidth(); 371 sal_uInt32 nDefaultObjectSizeHeight = rAppOpt.GetDefaultObjectSizeHeight(); 372 373 // calc position and size 374 Rectangle aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel())); 375 Point aPagePos = aVisArea.Center(); 376 aPagePos.X() -= nDefaultObjectSizeWidth / 2; 377 aPagePos.Y() -= nDefaultObjectSizeHeight / 2; 378 Rectangle aNewObjectRectangle(aPagePos, Size(nDefaultObjectSizeWidth, nDefaultObjectSizeHeight)); 379 380 ScDrawView* pDrView = GetScDrawView(); 381 382 if(pDrView) 383 { 384 SdrPageView* pPageView = pDrView->GetSdrPageView(); 385 386 if(pPageView) 387 { 388 // create the default object 389 SdrObject* pObj = pFuActual->CreateDefaultObject(nNewId, aNewObjectRectangle); 390 391 if(pObj) 392 { 393 // insert into page 394 pView->InsertObjectAtView(pObj, *pPageView); 395 396 if ( nNewId == SID_DRAW_CAPTION || nNewId == SID_DRAW_CAPTION_VERTICAL ) 397 { 398 // #105815# use KeyInput to start edit mode (FuText is created). 399 // For FuText objects, edit mode is handled within CreateDefaultObject. 400 // KEY_F2 is handled in FuDraw::KeyInput. 401 402 pFuActual->KeyInput( KeyEvent( 0, KeyCode( KEY_F2 ) ) ); 403 } 404 } 405 } 406 } 407 } 408 } 409 410 void ScTabViewShell::GetDrawState(SfxItemSet &rSet) 411 { 412 SfxWhichIter aIter(rSet); 413 sal_uInt16 nWhich = aIter.FirstWhich(); 414 415 while ( nWhich ) 416 { 417 switch ( nWhich ) 418 { 419 case SID_INSERT_DRAW: 420 { 421 // SID_OBJECT_SELECT nur, wenn "harter" Selektionsmodus 422 sal_uInt16 nPutId = nDrawSfxId; 423 if ( nPutId == SID_OBJECT_SELECT && !IsDrawSelMode() ) 424 nPutId = USHRT_MAX; 425 // nur die Images, die auch auf dem Controller liegen 426 if ( nPutId != SID_OBJECT_SELECT && 427 nPutId != SID_DRAW_LINE && 428 nPutId != SID_DRAW_RECT && 429 nPutId != SID_DRAW_ELLIPSE && 430 nPutId != SID_DRAW_POLYGON_NOFILL && 431 nPutId != SID_DRAW_BEZIER_NOFILL && 432 nPutId != SID_DRAW_FREELINE_NOFILL && 433 nPutId != SID_DRAW_ARC && 434 nPutId != SID_DRAW_PIE && 435 nPutId != SID_DRAW_CIRCLECUT && 436 nPutId != SID_DRAW_TEXT && 437 nPutId != SID_DRAW_TEXT_VERTICAL && 438 nPutId != SID_DRAW_TEXT_MARQUEE && 439 nPutId != SID_DRAW_CAPTION && 440 nPutId != SID_DRAW_CAPTION_VERTICAL ) 441 nPutId = USHRT_MAX; 442 SfxAllEnumItem aItem( nWhich, nPutId ); 443 if ( !SvtLanguageOptions().IsVerticalTextEnabled() ) 444 { 445 aItem.DisableValue( SID_DRAW_TEXT_VERTICAL ); 446 aItem.DisableValue( SID_DRAW_CAPTION_VERTICAL ); 447 } 448 rSet.Put( aItem ); 449 } 450 break; 451 452 case SID_DRAW_CHART: 453 { 454 sal_Bool bOle = GetViewFrame()->GetFrame().IsInPlace(); 455 if ( bOle || !SvtModuleOptions().IsChart() ) 456 rSet.DisableItem( nWhich ); 457 } 458 break; 459 460 case SID_OBJECT_SELECT: // wichtig fuer den ollen Control-Controller 461 rSet.Put( SfxBoolItem( nWhich, nDrawSfxId == SID_OBJECT_SELECT && IsDrawSelMode() ) ); 462 break; 463 } 464 nWhich = aIter.NextWhich(); 465 } 466 } 467 468 sal_Bool ScTabViewShell::SelectObject( const String& rName ) 469 { 470 ScDrawView* pView = GetViewData()->GetScDrawView(); 471 if (!pView) 472 return sal_False; 473 474 sal_Bool bFound = pView->SelectObject( rName ); 475 // DrawShell etc. is handled in MarkListHasChanged 476 477 return bFound; 478 } 479 480 481 482