cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / view / tabcontr.cxx
blob68baa2b8067d1459334eaae9b3e01292a5701f5e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <TabControl.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <sfx2/dispatch.hxx>
24 #include <vcl/commandevent.hxx>
25 #include <vcl/vclevent.hxx>
27 #include <app.hrc>
29 #include <DrawViewShell.hxx>
30 #include <helpids.h>
31 #include <View.hxx>
32 #include <drawdoc.hxx>
33 #include <DrawDocShell.hxx>
35 namespace sd {
38 TabControl::TabControlTransferable::~TabControlTransferable()
42 void TabControl::TabControlTransferable::AddSupportedFormats()
44 AddFormat( SotClipboardFormatId::STARDRAW_TABBAR );
47 bool TabControl::TabControlTransferable::GetData( const css::datatransfer::DataFlavor& /*rFlavor*/, const OUString& /*rDestDoc*/ )
49 return false;
52 void TabControl::TabControlTransferable::DragFinished( sal_Int8 /*nDropAction*/ )
54 mrParent.DragFinished();
57 TabControl::TabControl(DrawViewShell* pViewSh, vcl::Window* pParent) :
58 TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_SIZEABLE | WB_DRAG) ),
59 DragSourceHelper( this ),
60 DropTargetHelper( this ),
61 pDrViewSh(pViewSh),
62 bInternalMove(false)
64 EnableEditMode();
65 SetSizePixel(Size(0, 0));
66 SetMaxPageWidth( 150 );
67 SetHelpId( HID_SD_TABBAR_PAGES );
70 TabControl::~TabControl()
72 disposeOnce();
75 void TabControl::dispose()
77 DragSourceHelper::dispose();
78 DropTargetHelper::dispose();
79 TabBar::dispose();
82 void TabControl::Select()
84 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
85 pDispatcher->Execute(SID_SWITCHPAGE, SfxCallMode::ASYNCHRON |
86 SfxCallMode::RECORD);
89 void TabControl::MouseButtonDown(const MouseEvent& rMEvt)
91 if (rMEvt.IsLeft()
92 && !rMEvt.IsMod1()
93 && !rMEvt.IsMod2()
94 && !rMEvt.IsShift())
96 Point aPos = PixelToLogic( rMEvt.GetPosPixel() );
97 sal_uInt16 aPageId = GetPageId(aPos);
99 //initialize
100 if (aPageId == 0)
102 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
104 pDispatcher->Execute(SID_INSERTPAGE_QUICK,
105 SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
109 // A single left click with pressed control key on a tab page first
110 // switches to that page before the usual handling (copying with drag
111 // and drop) takes place.
112 else if (rMEvt.IsLeft() && rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift())
114 pDrViewSh->SwitchPage (GetPageId (rMEvt.GetPosPixel()) - 1);
117 // When only the right button is pressed then first process a
118 // synthesized left button click to make the page the current one
119 // whose tab has been clicked. When then the actual right button
120 // click is processed the resulting context menu relates to the
121 // now current page.
122 if (rMEvt.IsRight() && ! rMEvt.IsLeft())
124 MouseEvent aSyntheticEvent (
125 rMEvt.GetPosPixel(),
126 rMEvt.GetClicks(),
127 rMEvt.GetMode(),
128 MOUSE_LEFT,
129 rMEvt.GetModifier());
130 TabBar::MouseButtonDown(aSyntheticEvent);
133 TabBar::MouseButtonDown(rMEvt);
136 void TabControl::DoubleClick()
138 if (GetCurPageId() != 0)
140 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
141 pDispatcher->Execute( SID_MODIFYPAGE,
142 SfxCallMode::SYNCHRON | SfxCallMode::RECORD );
146 void TabControl::StartDrag( sal_Int8, const Point& )
148 bInternalMove = true;
150 // object is delete by reference mechanism
151 ( new TabControl::TabControlTransferable( *this ) )->StartDrag( this, DND_ACTION_COPYMOVE );
154 void TabControl::DragFinished()
156 bInternalMove = false;
159 sal_Int8 TabControl::AcceptDrop( const AcceptDropEvent& rEvt )
161 sal_Int8 nRet = DND_ACTION_NONE;
163 if( rEvt.mbLeaving )
164 EndSwitchPage();
166 if( !pDrViewSh->GetDocSh()->IsReadOnly() )
168 SdDrawDocument* pDoc = pDrViewSh->GetDoc();
169 Point aPos( rEvt.maPosPixel );
171 if( bInternalMove )
173 if( rEvt.mbLeaving || ( pDrViewSh->GetEditMode() == EditMode::MasterPage ) )
174 HideDropPos();
175 else
177 ShowDropPos( aPos );
178 nRet = rEvt.mnAction;
181 else
183 HideDropPos();
185 sal_Int32 nPageId = GetPageId( aPos ) - 1;
187 if( ( nPageId >= 0 ) && pDoc->GetPage( static_cast<sal_uInt16>(nPageId) ) )
189 nRet = pDrViewSh->AcceptDrop( rEvt, *this, nullptr, static_cast<sal_uInt16>(nPageId), SDRLAYER_NOTFOUND );
190 SwitchPage( aPos );
195 return nRet;
198 sal_Int8 TabControl::ExecuteDrop( const ExecuteDropEvent& rEvt )
200 SdDrawDocument* pDoc = pDrViewSh->GetDoc();
201 Point aPos( rEvt.maPosPixel );
202 sal_Int8 nRet = DND_ACTION_NONE;
204 if( bInternalMove )
206 sal_uInt16 nDropPos = ShowDropPos( aPos );
207 assert(nDropPos > 0);
208 sal_uInt16 nPageId = nDropPos - 1;
210 switch (rEvt.mnAction)
212 case DND_ACTION_MOVE:
213 if( pDrViewSh->IsSwitchPageAllowed() && pDoc->MovePages( nPageId ) )
215 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
216 pDispatcher->Execute(SID_SWITCHPAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
218 break;
220 case DND_ACTION_COPY:
222 // Copying the selected page to the place that rEvt points
223 // takes place in three steps:
224 // 1. Create a copy of the selected page. This copy will
225 // lie directly behind the selected page.
226 // 2. Move the copy to the desired place.
227 // 3. Select the copy.
228 if (pDrViewSh->IsSwitchPageAllowed())
230 // 1. Create a copy.
231 sal_uInt16 nPageNumOfCopy = pDoc->DuplicatePage (GetCurPageId() - 1);
232 // 2. Move page. For this first switch to the copy:
233 // MovePages operates on the currently selected page(s).
234 pDrViewSh->SwitchPage (nPageNumOfCopy);
235 // Adapt target page id when necessary, i.e. page copy
236 // has been inserted in front of the target page.
237 sal_uInt16 nPageNum = nPageId;
238 if ((nPageNumOfCopy <= nPageNum) && (nPageNum != sal_uInt16(-1)))
239 nPageNum += 1;
240 if (pDoc->MovePages(nPageNum))
242 // 3. Switch to the copy that has been moved to its
243 // final destination. Use an asynchron slot call to
244 // be executed after the still pending ones.
245 if (nPageNumOfCopy >= nPageNum || (nPageNum == sal_uInt16(-1)))
246 nPageNum += 1;
247 SetCurPageId (GetPageId(nPageNum));
248 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
249 pDispatcher->Execute(SID_SWITCHPAGE,
250 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
254 break;
258 nRet = rEvt.mnAction;
260 else
262 sal_Int32 nPageId = GetPageId( aPos ) - 1;
264 if( ( nPageId >= 0 ) && pDoc->GetPage( static_cast<sal_uInt16>(nPageId) ) )
266 nRet = pDrViewSh->ExecuteDrop( rEvt, *this, nullptr, static_cast<sal_uInt16>(nPageId), SDRLAYER_NOTFOUND );
270 HideDropPos();
271 EndSwitchPage();
273 return nRet;
276 void TabControl::Command(const CommandEvent& rCEvt)
278 if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
280 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
281 pDispatcher->ExecutePopup(u"pagetab"_ustr);
285 bool TabControl::StartRenaming()
287 bool bOK = false;
289 if (pDrViewSh->GetPageKind() == PageKind::Standard)
291 bOK = true;
293 ::sd::View* pView = pDrViewSh->GetView();
295 if ( pView->IsTextEdit() )
296 pView->SdrEndTextEdit();
299 return bOK;
302 TabBarAllowRenamingReturnCode TabControl::AllowRenaming()
304 bool bOK = true;
306 OUString aNewName( GetEditText() );
307 OUString aCompareName( GetPageText( GetEditPageId() ) );
309 if( aCompareName != aNewName )
311 // rename page
312 if (pDrViewSh->GetDocSh()->CheckPageName(GetFrameWeld(), aNewName))
314 SetEditText( aNewName );
315 EndRenaming();
317 else
319 bOK = false;
322 return bOK ? TABBAR_RENAMING_YES : TABBAR_RENAMING_NO;
325 void TabControl::EndRenaming()
327 if( !IsEditModeCanceled() )
328 pDrViewSh->RenameSlide( GetEditPageId(), GetEditText() );
331 void TabControl::ActivatePage()
333 if ( /*IsInSwitching && */ pDrViewSh->IsSwitchPageAllowed() )
335 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher();
336 pDispatcher->Execute(SID_SWITCHPAGE,
337 SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
341 bool TabControl::DeactivatePage()
343 return pDrViewSh->IsSwitchPageAllowed();
346 void TabControl::SendActivatePageEvent()
348 CallEventListeners (VclEventId::TabbarPageActivated,
349 reinterpret_cast<void*>(GetCurPageId()));
352 void TabControl::SendDeactivatePageEvent()
354 CallEventListeners (VclEventId::TabbarPageDeactivated,
355 reinterpret_cast<void*>(GetCurPageId()));
358 } // end of namespace sd
360 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */