1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <sal/config.h>
21
22 #include <utility>
23
24 #include "MasterPagesSelector.hxx"
25
26 #include "MasterPageContainer.hxx"
27 #include "DocumentHelper.hxx"
28 #include <pres.hxx>
29 #include <drawdoc.hxx>
30 #include <sdpage.hxx>
31 #include <app.hrc>
32
33 #include <DrawController.hxx>
34 #include <SlideSorterViewShell.hxx>
35 #include "PreviewValueSet.hxx"
36 #include <ViewShellBase.hxx>
37 #include <vcl/commandevent.hxx>
38 #include <vcl/image.hxx>
39 #include <vcl/floatwin.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <sfx2/sidebar/Theme.hxx>
43 #include <memory>
44
45 using namespace ::com::sun::star::text;
46
47 namespace sd { namespace sidebar {
48
49 /** menu entry that is executed as default action when the left mouse button is
50 clicked over a master page.
51 */
52 static const char gsDefaultClickAction[] = "applyselect";
53
MasterPagesSelector(vcl::Window * pParent,SdDrawDocument & rDocument,ViewShellBase & rBase,const std::shared_ptr<MasterPageContainer> & rpContainer,const css::uno::Reference<css::ui::XSidebar> & rxSidebar)54 MasterPagesSelector::MasterPagesSelector (
55 vcl::Window* pParent,
56 SdDrawDocument& rDocument,
57 ViewShellBase& rBase,
58 const std::shared_ptr<MasterPageContainer>& rpContainer,
59 const css::uno::Reference<css::ui::XSidebar>& rxSidebar)
60 : PreviewValueSet(pParent),
61 maMutex(),
62 mpContainer(rpContainer),
63 mrDocument(rDocument),
64 mrBase(rBase),
65 maCurrentItemList(),
66 maTokenToValueSetIndex(),
67 maLockedMasterPages(),
68 mxSidebar(rxSidebar)
69 {
70 PreviewValueSet::SetSelectHdl (
71 LINK(this, MasterPagesSelector, ClickHandler));
72 PreviewValueSet::SetRightMouseClickHandler (
73 LINK(this, MasterPagesSelector, RightClickHandler));
74 PreviewValueSet::SetStyle(PreviewValueSet::GetStyle() | WB_NO_DIRECTSELECT);
75
76 if ( GetDPIScaleFactor() > 1 )
77 mpContainer->SetPreviewSize(MasterPageContainer::LARGE);
78
79 PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel());
80 PreviewValueSet::Show();
81
82 SetBackground(sfx2::sidebar::Theme::GetWallpaper(sfx2::sidebar::Theme::Paint_PanelBackground));
83 SetColor(sfx2::sidebar::Theme::GetColor(sfx2::sidebar::Theme::Paint_PanelBackground));
84
85 Link<MasterPageContainerChangeEvent&,void> aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
86 mpContainer->AddChangeListener(aChangeListener);
87 }
88
~MasterPagesSelector()89 MasterPagesSelector::~MasterPagesSelector()
90 {
91 disposeOnce();
92 }
93
dispose()94 void MasterPagesSelector::dispose()
95 {
96 Clear();
97 UpdateLocks(ItemList());
98
99 Link<MasterPageContainerChangeEvent&,void> aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
100 mpContainer->RemoveChangeListener(aChangeListener);
101 mpContainer.reset();
102 PreviewValueSet::dispose();
103 }
104
LateInit()105 void MasterPagesSelector::LateInit()
106 {
107 }
108
GetPreferredHeight(sal_Int32 nWidth)109 sal_Int32 MasterPagesSelector::GetPreferredHeight (sal_Int32 nWidth)
110 {
111 const ::osl::MutexGuard aGuard (maMutex);
112
113 return PreviewValueSet::GetPreferredHeight (nWidth);
114 }
115
UpdateLocks(const ItemList & rItemList)116 void MasterPagesSelector::UpdateLocks (const ItemList& rItemList)
117 {
118 ItemList aNewLockList;
119
120 // In here we first lock the master pages in the given list and then
121 // release the locks acquired in a previous call to this method. When
122 // this were done the other way round the lock count of some master
123 // pages might drop temporarily to 0 and would lead to unnecessary
124 // deletion and re-creation of MasterPageDescriptor objects.
125
126 // Lock the master pages in the given list.
127 for (const auto& rItem : rItemList)
128 {
129 mpContainer->AcquireToken(rItem);
130 aNewLockList.push_back(rItem);
131 }
132
133 // Release the previously locked master pages.
134 for (const auto& rPage : maLockedMasterPages)
135 mpContainer->ReleaseToken(rPage);
136
137 maLockedMasterPages.swap(aNewLockList);
138 }
139
Fill()140 void MasterPagesSelector::Fill()
141 {
142 ::std::unique_ptr<ItemList> pItemList (new ItemList);
143
144 Fill(*pItemList);
145
146 UpdateLocks(*pItemList);
147 UpdateItemList(std::move(pItemList));
148 }
149
GetContextMenuUIFile() const150 OUString MasterPagesSelector::GetContextMenuUIFile() const
151 {
152 return "modules/simpress/ui/mastermenu.ui";
153 }
154
IMPL_LINK_NOARG(MasterPagesSelector,ClickHandler,ValueSet *,void)155 IMPL_LINK_NOARG(MasterPagesSelector, ClickHandler, ValueSet*, void)
156 {
157 // We use the framework to assign the clicked-on master page because we
158 // so use the same mechanism as the context menu does (where we do not
159 // have the option to call the assignment method directly.)
160 ExecuteCommand(gsDefaultClickAction);
161 }
162
IMPL_LINK(MasterPagesSelector,RightClickHandler,const MouseEvent &,rEvent,void)163 IMPL_LINK(MasterPagesSelector, RightClickHandler, const MouseEvent&, rEvent, void)
164 {
165 // Here we only prepare the display of the context menu: the item under
166 // the mouse is selected. The actual display of the context menu is
167 // done in ContextMenuCallback which is called indirectly through
168 // PreviewValueSet::Command().
169 PreviewValueSet::GrabFocus ();
170 PreviewValueSet::ReleaseMouse();
171 SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
172 if (pViewFrame != nullptr)
173 {
174 SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
175 if (pDispatcher != nullptr)
176 {
177 sal_uInt16 nIndex = PreviewValueSet::GetItemId (rEvent.GetPosPixel());
178 if (nIndex > 0)
179 PreviewValueSet::SelectItem (nIndex);
180 }
181 }
182 }
183
Command(const CommandEvent & rEvent)184 void MasterPagesSelector::Command (const CommandEvent& rEvent)
185 {
186 switch (rEvent.GetCommand())
187 {
188 case CommandEventId::ContextMenu:
189 {
190 // Use the currently selected item and show the popup menu in its
191 // center.
192 const sal_uInt16 nIndex = PreviewValueSet::GetSelectedItemId();
193 if (nIndex > 0)
194 {
195 // The position of the upper left corner of the context menu is
196 // taken either from the mouse position (when the command was sent
197 // as reaction to a right click) or in the center of the selected
198 // item (when the command was sent as reaction to Shift+F10.)
199 Point aPosition (rEvent.GetMousePosPixel());
200 if ( ! rEvent.IsMouseEvent())
201 {
202 ::tools::Rectangle aBBox (PreviewValueSet::GetItemRect(nIndex));
203 aPosition = aBBox.Center();
204 }
205
206 // Setup the menu.
207 VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), GetContextMenuUIFile(), "");
208 VclPtr<PopupMenu> pMenu(aBuilder.get_menu("menu"));
209 FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
210 if (pMenuWindow != nullptr)
211 pMenuWindow->SetPopupModeFlags(
212 pMenuWindow->GetPopupModeFlags() | FloatWinPopupFlags::NoMouseUpClose);
213 pMenu->SetSelectHdl(LINK(this, MasterPagesSelector, OnMenuItemSelected));
214
215 ProcessPopupMenu(*pMenu);
216
217 // Show the menu.
218 pMenu->Execute(this, ::tools::Rectangle(aPosition,Size(1,1)), PopupMenuFlags::ExecuteDown);
219 }
220 }
221 break;
222 default: break;
223 }
224 }
225
ProcessPopupMenu(Menu & rMenu)226 void MasterPagesSelector::ProcessPopupMenu (Menu& rMenu)
227 {
228 // Disable some entries.
229 if (mpContainer->GetPreviewSize() == MasterPageContainer::SMALL)
230 rMenu.EnableItem(rMenu.GetItemId("small"), false);
231 else
232 rMenu.EnableItem(rMenu.GetItemId("large"), false);
233 }
234
IMPL_LINK(MasterPagesSelector,OnMenuItemSelected,Menu *,pMenu,bool)235 IMPL_LINK(MasterPagesSelector, OnMenuItemSelected, Menu*, pMenu, bool)
236 {
237 if (pMenu == nullptr)
238 {
239 OSL_ENSURE(pMenu!=nullptr, "MasterPagesSelector::OnMenuItemSelected: illegal menu!");
240 return false;
241 }
242
243 pMenu->Deactivate();
244 ExecuteCommand(pMenu->GetCurItemIdent());
245 return false;
246 }
247
ExecuteCommand(const OString & rIdent)248 void MasterPagesSelector::ExecuteCommand(const OString &rIdent)
249 {
250 if (rIdent == "applyall")
251 {
252 mrBase.SetBusyState (true);
253 AssignMasterPageToAllSlides (GetSelectedMasterPage());
254 mrBase.SetBusyState (false);
255 }
256 else if (rIdent == "applyselect")
257 {
258 mrBase.SetBusyState (true);
259 AssignMasterPageToSelectedSlides (GetSelectedMasterPage());
260 mrBase.SetBusyState (false);
261 }
262 else if (rIdent == "large")
263 {
264 mrBase.SetBusyState (true);
265 mpContainer->SetPreviewSize(MasterPageContainer::LARGE);
266 mrBase.SetBusyState (false);
267 if (mxSidebar.is())
268 mxSidebar->requestLayout();
269 }
270 else if (rIdent == "small")
271 {
272 mrBase.SetBusyState (true);
273 mpContainer->SetPreviewSize(MasterPageContainer::SMALL);
274 mrBase.SetBusyState (false);
275 if (mxSidebar.is())
276 mxSidebar->requestLayout();
277 }
278 else if (rIdent == "edit")
279 {
280 using namespace ::com::sun::star;
281 uno::Reference<drawing::XDrawPage> xSelectedMaster;
282 SdPage* pMasterPage = GetSelectedMasterPage();
283 assert(pMasterPage); //rhbz#902884
284 if (pMasterPage)
285 xSelectedMaster.set(pMasterPage->getUnoPage(), uno::UNO_QUERY);
286 SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
287 if (pViewFrame != nullptr && xSelectedMaster.is())
288 {
289 SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
290 if (pDispatcher != nullptr)
291 {
292 sal_uInt16 nIndex = PreviewValueSet::GetSelectedItemId();
293 pDispatcher->Execute(SID_MASTERPAGE, SfxCallMode::SYNCHRON);
294 PreviewValueSet::SelectItem (nIndex);
295 mrBase.GetDrawController().setCurrentPage(xSelectedMaster);
296 }
297 }
298 }
299 }
300
IMPL_LINK(MasterPagesSelector,ContainerChangeListener,MasterPageContainerChangeEvent &,rEvent,void)301 IMPL_LINK(MasterPagesSelector, ContainerChangeListener, MasterPageContainerChangeEvent&, rEvent, void)
302 {
303 NotifyContainerChangeEvent(rEvent);
304 }
305
GetSelectedMasterPage()306 SdPage* MasterPagesSelector::GetSelectedMasterPage()
307 {
308 const ::osl::MutexGuard aGuard (maMutex);
309
310 SdPage* pMasterPage = nullptr;
311 sal_uInt16 nIndex = PreviewValueSet::GetSelectedItemId();
312 UserData* pData = GetUserData(nIndex);
313 if (pData != nullptr)
314 {
315 pMasterPage = mpContainer->GetPageObjectForToken(pData->second, true);
316 }
317 return pMasterPage;
318 }
319
320 /** Assemble a list of all slides of the document and pass it to
321 AssignMasterPageToPageList().
322 */
AssignMasterPageToAllSlides(SdPage * pMasterPage)323 void MasterPagesSelector::AssignMasterPageToAllSlides (SdPage* pMasterPage)
324 {
325 if (pMasterPage == nullptr)
326 return;
327
328 sal_uInt16 nPageCount = mrDocument.GetSdPageCount(PageKind::Standard);
329 if (nPageCount == 0)
330 return;
331
332 // Get a list of all pages. As a little optimization we only
333 // include pages that do not already have the given master page
334 // assigned.
335 OUString sFullLayoutName(pMasterPage->GetLayoutName());
336 ::sd::slidesorter::SharedPageSelection pPageList (
337 new ::sd::slidesorter::SlideSorterViewShell::PageSelection);
338 for (sal_uInt16 nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
339 {
340 SdPage* pPage = mrDocument.GetSdPage (nPageIndex, PageKind::Standard);
341 if (pPage != nullptr && pPage->GetLayoutName() != sFullLayoutName)
342 {
343 pPageList->push_back (pPage);
344 }
345 }
346
347 AssignMasterPageToPageList(pMasterPage, pPageList);
348 }
349
350 /** Assemble a list of the currently selected slides (selected in a visible
351 slide sorter) and pass it to AssignMasterPageToPageList().
352 */
AssignMasterPageToSelectedSlides(SdPage * pMasterPage)353 void MasterPagesSelector::AssignMasterPageToSelectedSlides (
354 SdPage* pMasterPage)
355 {
356 using namespace ::sd::slidesorter;
357 using namespace ::sd::slidesorter::controller;
358
359 if (pMasterPage == nullptr)
360 return;
361
362 // Find a visible slide sorter.
363 SlideSorterViewShell* pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
364 if (pSlideSorter == nullptr)
365 return;
366
367 // Get a list of selected pages.
368 SharedPageSelection pPageSelection = pSlideSorter->GetPageSelection();
369 if (pPageSelection->empty())
370 return;
371
372 AssignMasterPageToPageList(pMasterPage, pPageSelection);
373
374 // Restore the previous selection.
375 pSlideSorter->SetPageSelection(pPageSelection);
376 }
377
AssignMasterPageToPageList(SdPage * pMasterPage,const std::shared_ptr<std::vector<SdPage * >> & rPageList)378 void MasterPagesSelector::AssignMasterPageToPageList (
379 SdPage* pMasterPage,
380 const std::shared_ptr<std::vector<SdPage*>>& rPageList)
381 {
382 DocumentHelper::AssignMasterPageToPageList(mrDocument, pMasterPage, rPageList);
383 }
384
NotifyContainerChangeEvent(const MasterPageContainerChangeEvent & rEvent)385 void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent)
386 {
387 const ::osl::MutexGuard aGuard (maMutex);
388
389 switch (rEvent.meEventType)
390 {
391 case MasterPageContainerChangeEvent::EventType::SIZE_CHANGED:
392 PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel());
393 UpdateAllPreviews();
394 break;
395
396 case MasterPageContainerChangeEvent::EventType::PREVIEW_CHANGED:
397 {
398 int nIndex (GetIndexForToken(rEvent.maChildToken));
399 if (nIndex >= 0)
400 {
401 PreviewValueSet::SetItemImage (
402 static_cast<sal_uInt16>(nIndex),
403 mpContainer->GetPreviewForToken(rEvent.maChildToken));
404 PreviewValueSet::Invalidate(PreviewValueSet::GetItemRect(static_cast<sal_uInt16>(nIndex)));
405 }
406 }
407 break;
408
409 case MasterPageContainerChangeEvent::EventType::DATA_CHANGED:
410 {
411 InvalidateItem(rEvent.maChildToken);
412 Fill();
413 }
414 break;
415
416 case MasterPageContainerChangeEvent::EventType::CHILD_REMOVED:
417 {
418 int nIndex (GetIndexForToken(rEvent.maChildToken));
419 SetItem(nIndex, MasterPageContainer::NIL_TOKEN);
420 break;
421 }
422
423 default:
424 break;
425 }
426 }
427
GetUserData(int nIndex) const428 MasterPagesSelector::UserData* MasterPagesSelector::GetUserData (int nIndex) const
429 {
430 const ::osl::MutexGuard aGuard (maMutex);
431
432 if (nIndex>0 && static_cast<unsigned int>(nIndex)<=PreviewValueSet::GetItemCount())
433 return static_cast<UserData*>(PreviewValueSet::GetItemData(static_cast<sal_uInt16>(nIndex)));
434 else
435 return nullptr;
436 }
437
SetUserData(int nIndex,std::unique_ptr<UserData> pData)438 void MasterPagesSelector::SetUserData (int nIndex, std::unique_ptr<UserData> pData)
439 {
440 const ::osl::MutexGuard aGuard (maMutex);
441
442 delete GetUserData(nIndex);
443 PreviewValueSet::SetItemData(static_cast<sal_uInt16>(nIndex), pData.release());
444 }
445
SetItem(sal_uInt16 nIndex,MasterPageContainer::Token aToken)446 void MasterPagesSelector::SetItem (
447 sal_uInt16 nIndex,
448 MasterPageContainer::Token aToken)
449 {
450 const ::osl::MutexGuard aGuard (maMutex);
451
452 RemoveTokenToIndexEntry(nIndex,aToken);
453
454 if (nIndex <= 0)
455 return;
456
457 if (aToken != MasterPageContainer::NIL_TOKEN)
458 {
459 Image aPreview (mpContainer->GetPreviewForToken(aToken));
460 MasterPageContainer::PreviewState eState (mpContainer->GetPreviewState(aToken));
461
462 if (aPreview.GetSizePixel().Width()>0)
463 {
464 if (PreviewValueSet::GetItemPos(nIndex) != VALUESET_ITEM_NOTFOUND)
465 {
466 PreviewValueSet::SetItemImage(nIndex,aPreview);
467 PreviewValueSet::SetItemText(nIndex, mpContainer->GetPageNameForToken(aToken));
468 }
469 else
470 {
471 PreviewValueSet::InsertItem (
472 nIndex,
473 aPreview,
474 mpContainer->GetPageNameForToken(aToken),
475 nIndex);
476 }
477 SetUserData(nIndex, std::make_unique<UserData>(nIndex,aToken));
478
479 AddTokenToIndexEntry(nIndex,aToken);
480 }
481
482 if (eState == MasterPageContainer::PS_CREATABLE)
483 mpContainer->RequestPreview(aToken);
484 }
485 else
486 {
487 PreviewValueSet::RemoveItem(nIndex);
488 }
489
490 }
491
AddTokenToIndexEntry(sal_uInt16 nIndex,MasterPageContainer::Token aToken)492 void MasterPagesSelector::AddTokenToIndexEntry (
493 sal_uInt16 nIndex,
494 MasterPageContainer::Token aToken)
495 {
496 const ::osl::MutexGuard aGuard (maMutex);
497
498 maTokenToValueSetIndex[aToken] = nIndex;
499 }
500
RemoveTokenToIndexEntry(sal_uInt16 nIndex,MasterPageContainer::Token aNewToken)501 void MasterPagesSelector::RemoveTokenToIndexEntry (
502 sal_uInt16 nIndex,
503 MasterPageContainer::Token aNewToken)
504 {
505 const ::osl::MutexGuard aGuard (maMutex);
506
507 UserData* pData = GetUserData(nIndex);
508 if (pData != nullptr)
509 {
510 // Get the token that the index pointed to previously.
511 MasterPageContainer::Token aOldToken (pData->second);
512
513 if (aNewToken != aOldToken
514 && nIndex == GetIndexForToken(aOldToken))
515 {
516 maTokenToValueSetIndex[aOldToken] = 0;
517 }
518 }
519 }
520
InvalidatePreview(const SdPage * pPage)521 void MasterPagesSelector::InvalidatePreview (const SdPage* pPage)
522 {
523 const ::osl::MutexGuard aGuard (maMutex);
524
525 for (size_t nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
526 {
527 UserData* pData = GetUserData(nIndex);
528 if (pData != nullptr)
529 {
530 MasterPageContainer::Token aToken (pData->second);
531 if (pPage == mpContainer->GetPageObjectForToken(aToken,false))
532 {
533 mpContainer->InvalidatePreview(aToken);
534 mpContainer->RequestPreview(aToken);
535 break;
536 }
537 }
538 }
539 }
540
UpdateAllPreviews()541 void MasterPagesSelector::UpdateAllPreviews()
542 {
543 const ::osl::MutexGuard aGuard (maMutex);
544
545 for (size_t nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
546 {
547 UserData* pData = GetUserData(nIndex);
548 if (pData != nullptr)
549 {
550 MasterPageContainer::Token aToken (pData->second);
551 PreviewValueSet::SetItemImage(
552 nIndex,
553 mpContainer->GetPreviewForToken(aToken));
554 if (mpContainer->GetPreviewState(aToken) == MasterPageContainer::PS_CREATABLE)
555 mpContainer->RequestPreview(aToken);
556 }
557 }
558 PreviewValueSet::Rearrange();
559 }
560
ClearPageSet()561 void MasterPagesSelector::ClearPageSet()
562 {
563 const ::osl::MutexGuard aGuard (maMutex);
564
565 for (size_t nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
566 {
567 UserData* pData = GetUserData(nIndex);
568 delete pData;
569 }
570 PreviewValueSet::Clear();
571 }
572
SetHelpId(const OString & aId)573 void MasterPagesSelector::SetHelpId( const OString& aId )
574 {
575 const ::osl::MutexGuard aGuard (maMutex);
576
577 PreviewValueSet::SetHelpId( aId );
578 }
579
GetIndexForToken(MasterPageContainer::Token aToken) const580 sal_Int32 MasterPagesSelector::GetIndexForToken (MasterPageContainer::Token aToken) const
581 {
582 const ::osl::MutexGuard aGuard (maMutex);
583
584 TokenToValueSetIndex::const_iterator iIndex (maTokenToValueSetIndex.find(aToken));
585 if (iIndex != maTokenToValueSetIndex.end())
586 return iIndex->second;
587 else
588 return -1;
589 }
590
Clear()591 void MasterPagesSelector::Clear()
592 {
593 const ::osl::MutexGuard aGuard (maMutex);
594
595 ClearPageSet();
596 }
597
InvalidateItem(MasterPageContainer::Token aToken)598 void MasterPagesSelector::InvalidateItem (MasterPageContainer::Token aToken)
599 {
600 const ::osl::MutexGuard aGuard (maMutex);
601
602 auto iItem = std::find(maCurrentItemList.begin(), maCurrentItemList.end(), aToken);
603 if (iItem != maCurrentItemList.end())
604 *iItem = MasterPageContainer::NIL_TOKEN;
605 }
606
UpdateItemList(::std::unique_ptr<ItemList> && pNewItemList)607 void MasterPagesSelector::UpdateItemList (::std::unique_ptr<ItemList> && pNewItemList)
608 {
609 const ::osl::MutexGuard aGuard (maMutex);
610
611 ItemList::const_iterator iNewItem (pNewItemList->begin());
612 ItemList::const_iterator iCurrentItem (maCurrentItemList.begin());
613 ItemList::const_iterator iNewEnd (pNewItemList->end());
614 ItemList::const_iterator iCurrentEnd (maCurrentItemList.end());
615 sal_uInt16 nIndex (1);
616
617 // Update existing items.
618 for ( ; iNewItem!=iNewEnd && iCurrentItem!=iCurrentEnd; ++iNewItem, ++iCurrentItem,++nIndex)
619 {
620 if (*iNewItem != *iCurrentItem)
621 {
622 SetItem(nIndex,*iNewItem);
623 }
624 }
625
626 // Append new items.
627 for ( ; iNewItem!=iNewEnd; ++iNewItem,++nIndex)
628 {
629 SetItem(nIndex,*iNewItem);
630 }
631
632 // Remove trailing items.
633 for ( ; iCurrentItem!=iCurrentEnd; ++iCurrentItem,++nIndex)
634 {
635 SetItem(nIndex,MasterPageContainer::NIL_TOKEN);
636 }
637
638 maCurrentItemList.swap(*pNewItemList);
639
640 PreviewValueSet::Rearrange();
641 if (mxSidebar.is())
642 mxSidebar->requestLayout();
643 }
644
GetHeightForWidth(const sal_Int32 nWidth)645 css::ui::LayoutSize MasterPagesSelector::GetHeightForWidth (const sal_Int32 nWidth)
646 {
647 const sal_Int32 nHeight (GetPreferredHeight(nWidth));
648 return css::ui::LayoutSize(nHeight,nHeight,nHeight);
649 }
650
651 } } // end of namespace sd::sidebar
652
653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
654