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