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