xref: /trunk/main/sd/source/ui/view/tabcontr.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_sd.hxx"
30 
31 #include "TabControl.hxx"
32 
33 #include <sfx2/viewfrm.hxx>
34 #include <svx/svdlayer.hxx>
35 #include <svx/svdpagv.hxx>
36 #include <sfx2/dispatch.hxx>
37 
38 
39 #include "sdattr.hxx"
40 #include "app.hxx"
41 #include "app.hrc"
42 #include "glob.hrc"
43 #include "res_bmp.hrc"
44 #include "DrawViewShell.hxx"
45 #include "GraphicViewShell.hxx"
46 #include "helpids.h"
47 #include "View.hxx"
48 #include "sdpage.hxx"
49 #include "drawdoc.hxx"
50 #include "Window.hxx"
51 #include "unmodpg.hxx"
52 #include "DrawDocShell.hxx"
53 #include "sdresid.hxx"
54 
55 
56 namespace sd {
57 
58 #define SWITCH_TIMEOUT  20
59 
60 // -----------------------------------------
61 // - SdTabControl::SdPageObjsTransferable -
62 // -----------------------------------------
63 
64 TabControl::TabControlTransferable::~TabControlTransferable()
65 {
66 }
67 
68 // -----------------------------------------------------------------------------
69 
70 void TabControl::TabControlTransferable::AddSupportedFormats()
71 {
72     AddFormat( SOT_FORMATSTR_ID_STARDRAW_TABBAR );
73 }
74 
75 // -----------------------------------------------------------------------------
76 
77 sal_Bool TabControl::TabControlTransferable::GetData( const ::com::sun::star::datatransfer::DataFlavor& )
78 {
79     return sal_False;
80 }
81 
82 // -----------------------------------------------------------------------------
83 
84 void TabControl::TabControlTransferable::DragFinished( sal_Int8 nDropAction )
85 {
86     mrParent.DragFinished( nDropAction );
87 }
88 
89 /*************************************************************************
90 |*
91 |* Standard-Konstruktor
92 |*
93 \************************************************************************/
94 
95 TabControl::TabControl(DrawViewShell* pViewSh, Window* pParent) :
96     TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_SIZEABLE | WB_DRAG) ),
97     DragSourceHelper( this ),
98     DropTargetHelper( this ),
99     pDrViewSh(pViewSh),
100     bInternalMove(sal_False)
101 {
102     EnableEditMode();
103     SetSizePixel(Size(0, 0));
104     SetMaxPageWidth( 150 );
105     SetHelpId( HID_SD_TABBAR_PAGES );
106 }
107 
108 /*************************************************************************
109 |*
110 |* Destruktor
111 |*
112 \************************************************************************/
113 
114 TabControl::~TabControl()
115 {
116 }
117 
118 /*************************************************************************
119 |*
120 \************************************************************************/
121 
122 void TabControl::Select()
123 {
124     SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
125     pDispatcher->Execute(SID_SWITCHPAGE, SFX_CALLMODE_ASYNCHRON |
126                             SFX_CALLMODE_RECORD);
127 }
128 
129 /*************************************************************************
130 |*
131 \************************************************************************/
132 
133 void  TabControl::MouseButtonDown(const MouseEvent& rMEvt)
134 {
135     if (rMEvt.IsLeft()
136         && !rMEvt.IsMod1()
137         && !rMEvt.IsMod2()
138         && !rMEvt.IsShift())
139     {
140         Point aPos = PixelToLogic( rMEvt.GetPosPixel() );
141         sal_uInt16 aPageId = GetPageId(aPos);
142 
143         if (aPageId == 0)
144         {
145             SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
146 
147             pDispatcher->Execute(SID_INSERTPAGE_QUICK,
148                                 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);
149         }
150     }
151 
152     // A single left click with pressed control key on a tab page first
153     // switches to that page before the usual handling (copying with drag
154     // and drop) takes place.
155     else if (rMEvt.IsLeft() && rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift())
156     {
157         pDrViewSh->SwitchPage (GetPageId (rMEvt.GetPosPixel()) - 1);
158     }
159 
160     // When only the right button is pressed then first process a
161     // synthesized left button click to make the page the current one
162     // whose tab has been clicked.  When then the actual right button
163     // click is processed the resulting context menu relates to the
164     // now current page.
165     if (rMEvt.IsRight() && ! rMEvt.IsLeft())
166     {
167         MouseEvent aSyntheticEvent (
168             rMEvt.GetPosPixel(),
169             rMEvt.GetClicks(),
170             rMEvt.GetMode(),
171             MOUSE_LEFT,
172             rMEvt.GetModifier());
173         TabBar::MouseButtonDown(aSyntheticEvent);
174     }
175 
176     TabBar::MouseButtonDown(rMEvt);
177 }
178 
179 /*************************************************************************
180 |*
181 \************************************************************************/
182 
183 void TabControl::DoubleClick()
184 {
185     if (GetCurPageId() != 0)
186     {
187         SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
188         pDispatcher->Execute( SID_MODIFYPAGE,
189                         SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
190     }
191 }
192 
193 /*************************************************************************
194 |*
195 |* StartDrag-Request
196 |*
197 \************************************************************************/
198 
199 void TabControl::StartDrag( sal_Int8, const Point& )
200 {
201     bInternalMove = sal_True;
202 
203     // object is delete by reference mechanismn
204     ( new TabControl::TabControlTransferable( *this ) )->StartDrag( this, DND_ACTION_COPYMOVE );
205 }
206 
207 /*************************************************************************
208 |*
209 |* DragFinished
210 |*
211 \************************************************************************/
212 
213 void TabControl::DragFinished( sal_Int8 )
214 {
215     bInternalMove = sal_False;
216 }
217 
218 /*************************************************************************
219 |*
220 |* AcceptDrop-Event
221 |*
222 \************************************************************************/
223 
224 sal_Int8 TabControl::AcceptDrop( const AcceptDropEvent& rEvt )
225 {
226     sal_Int8 nRet = DND_ACTION_NONE;
227 
228     if( rEvt.mbLeaving )
229         EndSwitchPage();
230 
231     if( !pDrViewSh->GetDocSh()->IsReadOnly() )
232     {
233         SdDrawDocument* pDoc = pDrViewSh->GetDoc();
234         Point           aPos( rEvt.maPosPixel );
235 
236         if( bInternalMove )
237         {
238             if( rEvt.mbLeaving || ( pDrViewSh->GetEditMode() == EM_MASTERPAGE ) )
239                 HideDropPos();
240             else
241             {
242                 ShowDropPos( aPos );
243                 nRet = rEvt.mnAction;
244             }
245         }
246         else
247         {
248             HideDropPos();
249 
250             sal_Int32 nPageId = GetPageId( aPos ) - 1;
251 
252             if( ( nPageId >= 0 ) && pDoc->GetPage( (sal_uInt16)nPageId ) )
253             {
254                 nRet = pDrViewSh->AcceptDrop( rEvt, *this, NULL, (sal_uInt16)nPageId, SDRLAYER_NOTFOUND );
255                 SwitchPage( aPos );
256             }
257         }
258     }
259 
260     return nRet;
261 }
262 
263 /*************************************************************************
264 |*
265 |* ExecuteDrop-Event
266 |*
267 \************************************************************************/
268 
269 sal_Int8 TabControl::ExecuteDrop( const ExecuteDropEvent& rEvt )
270 {
271     SdDrawDocument* pDoc = pDrViewSh->GetDoc();
272     Point           aPos( rEvt.maPosPixel );
273     sal_Int8        nRet = DND_ACTION_NONE;
274 
275     if( bInternalMove )
276     {
277         sal_uInt16 nPageId = ShowDropPos( aPos ) - 1;
278 
279         switch (rEvt.mnAction)
280         {
281             case DND_ACTION_MOVE:
282                 if( pDrViewSh->IsSwitchPageAllowed() && pDoc->MovePages( nPageId ) )
283                 {
284                     SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
285                     pDispatcher->Execute(SID_SWITCHPAGE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
286                 }
287                 break;
288 
289             case DND_ACTION_COPY:
290             {
291                 // Copying the selected page to the place that rEvt points
292                 // takes place in three steps:
293                 // 1. Create a copy of the selected page.  This copy will
294                 // lie directly behind the selected page.
295                 // 2. Move the copy to the desired place.
296                 // 3. Select the copy.
297                 if (pDrViewSh->IsSwitchPageAllowed())
298                 {
299                     // 1. Create a copy.
300                     sal_uInt16 nPageNumOfCopy = pDoc->DuplicatePage (GetCurPageId() - 1);
301                     // 2. Move page.  For this first switch to the copy:
302                     // MovePages operates on the currently selected page(s).
303                     pDrViewSh->SwitchPage (nPageNumOfCopy);
304                     // Adapt target page id when necessary, i.e. page copy
305                     // has been inserted in front of the target page.
306                     sal_uInt16 nPageNum = nPageId;
307                     if ((nPageNumOfCopy <= nPageNum) && (nPageNum != (sal_uInt16)-1))
308                         nPageNum += 1;
309                     if (pDoc->MovePages(nPageNum))
310                     {
311                         // 3. Switch to the copy that has been moved to its
312                         // final destination.  Use an asynchron slot call to
313                         // be executed after the still pending ones.
314                         if (nPageNumOfCopy >= nPageNum || (nPageNum == (sal_uInt16)-1))
315                             nPageNum += 1;
316                         SetCurPageId (GetPageId(nPageNum));
317                         SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
318                         pDispatcher->Execute(SID_SWITCHPAGE,
319                             SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
320                     }
321                 }
322 
323                 break;
324             }
325         }
326 
327         nRet = rEvt.mnAction;
328     }
329     else
330     {
331         sal_Int32 nPageId = GetPageId( aPos ) - 1;
332 
333         if( ( nPageId >= 0 ) && pDoc->GetPage( (sal_uInt16)nPageId ) )
334         {
335             nRet = pDrViewSh->ExecuteDrop( rEvt, *this, NULL, (sal_uInt16)nPageId, SDRLAYER_NOTFOUND );
336         }
337     }
338 
339     HideDropPos();
340     EndSwitchPage();
341 
342     return nRet;
343 }
344 
345 /*************************************************************************
346 |*
347 \************************************************************************/
348 
349 void TabControl::Command(const CommandEvent& rCEvt)
350 {
351     sal_uInt16 nCmd = rCEvt.GetCommand();
352 
353     if ( nCmd == COMMAND_CONTEXTMENU )
354     {
355         sal_Bool bGraphicShell = pDrViewSh->ISA(GraphicViewShell);
356         sal_uInt16 nResId = bGraphicShell ? RID_GRAPHIC_PAGETAB_POPUP :
357                                         RID_DRAW_PAGETAB_POPUP;
358         SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
359         pDispatcher->ExecutePopup( SdResId( nResId ) );
360     }
361 }
362 
363 /*************************************************************************
364 |*
365 \************************************************************************/
366 
367 long TabControl::StartRenaming()
368 {
369     sal_Bool bOK = sal_False;
370 
371     if (pDrViewSh->GetPageKind() == PK_STANDARD)
372     {
373         bOK = sal_True;
374 
375         ::sd::View* pView = pDrViewSh->GetView();
376 
377         if ( pView->IsTextEdit() )
378             pView->SdrEndTextEdit();
379     }
380 
381     return( bOK );
382 }
383 
384 /*************************************************************************
385 |*
386 \************************************************************************/
387 
388 long TabControl::AllowRenaming()
389 {
390     sal_Bool bOK = sal_True;
391 
392     String aNewName( GetEditText() );
393     String aCompareName( GetPageText( GetEditPageId() ) );
394 
395     if( aCompareName != aNewName )
396     {
397         // Seite umbenennen
398         if( pDrViewSh->GetDocSh()->CheckPageName( this, aNewName ) )
399         {
400             SetEditText( aNewName );
401             EndRenaming();
402         }
403         else
404         {
405             bOK = sal_False;
406         }
407     }
408     return( bOK );
409 }
410 
411 /*************************************************************************
412 |*
413 \************************************************************************/
414 
415 void TabControl::EndRenaming()
416 {
417     if( !IsEditModeCanceled() )
418         pDrViewSh->RenameSlide( GetEditPageId(), GetEditText() );
419 }
420 
421 
422 /*************************************************************************
423 |*
424 \************************************************************************/
425 
426 void TabControl::ActivatePage()
427 {
428     if ( /*IsInSwitching && */ pDrViewSh->IsSwitchPageAllowed() )
429     {
430         SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
431         pDispatcher->Execute(SID_SWITCHPAGE,
432                              SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
433     }
434 }
435 
436 
437 /*************************************************************************
438 |*
439 \************************************************************************/
440 
441 long TabControl::DeactivatePage()
442 {
443     return pDrViewSh->IsSwitchPageAllowed();
444 }
445 
446 
447 
448 
449 void TabControl::SendActivatePageEvent (void)
450 {
451     CallEventListeners (VCLEVENT_TABBAR_PAGEACTIVATED,
452         reinterpret_cast<void*>(GetCurPageId()));
453 }
454 
455 
456 
457 
458 void TabControl::SendDeactivatePageEvent (void)
459 {
460     CallEventListeners (VCLEVENT_TABBAR_PAGEDEACTIVATED,
461         reinterpret_cast<void*>(GetCurPageId()));
462 }
463 
464 } // end of namespace sd
465