xref: /AOO41X/main/sc/source/ui/view/tabvwsh2.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
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 
69 SdrView* __EXPORT ScTabViewShell::GetDrawView() const
70 {
71     return ((ScTabViewShell*)this)->GetScDrawView();    // GetScDrawView ist nicht-const
72 }
73 
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 
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 
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 
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