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 #include "precompiled_sd.hxx"
23 
24 #include "MasterPagesSelector.hxx"
25 
26 #include "MasterPageContainer.hxx"
27 #include "DocumentHelper.hxx"
28 #include "SidebarShellManager.hxx"
29 #include "pres.hxx"
30 #include "drawdoc.hxx"
31 #include "DrawDocShell.hxx"
32 #include "sdpage.hxx"
33 #include "glob.hxx"
34 #include "glob.hrc"
35 #include "app.hrc"
36 #include "res_bmp.hrc"
37 #include "strings.hrc"
38 #include "DrawViewShell.hxx"
39 #include "DrawController.hxx"
40 #include "SlideSorterViewShell.hxx"
41 #include "PreviewValueSet.hxx"
42 #include "ViewShellBase.hxx"
43 #include <sfx2/objface.hxx>
44 #include "sdresid.hxx"
45 #include "drawview.hxx"
46 #include <vcl/image.hxx>
47 #include <vcl/floatwin.hxx>
48 #include <svl/languageoptions.hxx>
49 #include <sfx2/app.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <sfx2/mnumgr.hxx>
52 #include <svl/itemset.hxx>
53 #include <svl/eitem.hxx>
54 #include <svx/dlgutil.hxx>
55 #include <svx/svdpagv.hxx>
56 #include <svx/svxids.hrc>
57 #include "FrameView.hxx"
58 #include "sdpage.hxx"
59 #include "stlpool.hxx"
60 #include "unmovss.hxx"
61 #include <sfx2/request.hxx>
62 #include <svl/itempool.hxx>
63 
64 
65 using namespace ::com::sun::star::text;
66 
67 
68 
69 namespace sd { namespace sidebar {
70 
71 
72 MasterPagesSelector::MasterPagesSelector (
73     ::Window* pParent,
74     SdDrawDocument& rDocument,
75     ViewShellBase& rBase,
76     const ::boost::shared_ptr<MasterPageContainer>& rpContainer,
77     const cssu::Reference<css::ui::XSidebar>& rxSidebar)
78     : PreviewValueSet(pParent),
79       maMutex(),
80       mpContainer(rpContainer),
81       mrDocument(rDocument),
82       mrBase(rBase),
83       mnDefaultClickAction(SID_TP_APPLY_TO_ALL_SLIDES),
84       maPreviewUpdateQueue(),
85       maCurrentItemList(),
86       maTokenToValueSetIndex(),
87       maLockedMasterPages(),
88       mxSidebar(rxSidebar)
89 {
90     PreviewValueSet::SetSelectHdl (
91         LINK(this, MasterPagesSelector, ClickHandler));
92 	PreviewValueSet::SetRightMouseClickHandler (
93         LINK(this, MasterPagesSelector, RightClickHandler));
94     PreviewValueSet::SetStyle(PreviewValueSet::GetStyle() | WB_NO_DIRECTSELECT);
95     PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel());
96     PreviewValueSet::Show();
97 
98     Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
99     mpContainer->AddChangeListener(aChangeListener);
100 }
101 
102 
103 
104 
105 MasterPagesSelector::~MasterPagesSelector (void)
106 {
107     Clear();
108     UpdateLocks(ItemList());
109 
110     Link aChangeListener (LINK(this,MasterPagesSelector,ContainerChangeListener));
111     mpContainer->RemoveChangeListener(aChangeListener);
112 }
113 
114 
115 
116 
117 void MasterPagesSelector::LateInit (void)
118 {
119 }
120 
121 
122 
123 
124 sal_Int32 MasterPagesSelector::GetPreferredWidth (sal_Int32 nHeight)
125 {
126     const ::osl::MutexGuard aGuard (maMutex);
127 
128     return PreviewValueSet::GetPreferredWidth (nHeight);
129 }
130 
131 
132 
133 
134 sal_Int32 MasterPagesSelector::GetPreferredHeight (sal_Int32 nWidth)
135 {
136     const ::osl::MutexGuard aGuard (maMutex);
137 
138     return PreviewValueSet::GetPreferredHeight (nWidth);
139 }
140 
141 
142 
143 
144 Size MasterPagesSelector::GetPreferredSize (void)
145 {
146     int nPreferredWidth = GetPreferredWidth(
147         PreviewValueSet::GetOutputSizePixel().Height());
148     int nPreferredHeight = GetPreferredHeight(nPreferredWidth);
149     return Size (nPreferredWidth, nPreferredHeight);
150 
151 }
152 
153 
154 
155 
156 void MasterPagesSelector::UpdateLocks (const ItemList& rItemList)
157 {
158     ItemList aNewLockList;
159 
160     // In here we first lock the master pages in the given list and then
161     // release the locks acquired in a previous call to this method.  When
162     // this were done the other way round the lock count of some master
163     // pages might drop temporarily to 0 and would lead to unnecessary
164     // deletion and re-creation of MasterPageDescriptor objects.
165 
166     // Lock the master pages in the given list.
167     ItemList::const_iterator iItem;
168     for (iItem=rItemList.begin(); iItem!=rItemList.end(); ++iItem)
169     {
170         mpContainer->AcquireToken(*iItem);
171         aNewLockList.push_back(*iItem);
172     }
173 
174     // Release the previously locked master pages.
175     ItemList::const_iterator iPage;
176     ItemList::const_iterator iEnd (maLockedMasterPages.end());
177     for (iPage=maLockedMasterPages.begin(); iPage!=iEnd; ++iPage)
178         mpContainer->ReleaseToken(*iPage);
179 
180     maLockedMasterPages.swap(aNewLockList);
181 }
182 
183 
184 
185 
186 void MasterPagesSelector::Fill (void)
187 {
188     ::std::auto_ptr<ItemList> pItemList (new ItemList());
189 
190     Fill(*pItemList);
191 
192     UpdateLocks(*pItemList);
193     UpdateItemList(pItemList);
194 }
195 
196 
197 
198 
199 ResId MasterPagesSelector::GetContextMenuResId (void) const
200 {
201     return SdResId(RID_TASKPANE_MASTERPAGESSELECTOR_POPUP);
202 }
203 
204 
205 
206 
207 IMPL_LINK(MasterPagesSelector, ClickHandler, PreviewValueSet*, EMPTYARG)
208 {
209     // We use the framework to assign the clicked-on master page because we
210     // so use the same mechanism as the context menu does (where we do not
211     // have the option to call the assignment method directly.)
212     ExecuteCommand(mnDefaultClickAction);
213 
214     return 0;
215 }
216 
217 
218 
219 
220 IMPL_LINK(MasterPagesSelector, RightClickHandler, MouseEvent*, pEvent)
221 {
222     // Here we only prepare the display of the context menu: the item under
223     // the mouse is selected.  The actual display of the context menu is
224     // done in ContextMenuCallback which is called indirectly through
225     // PreviewValueSet::Command().
226     PreviewValueSet::GrabFocus ();
227     PreviewValueSet::ReleaseMouse();
228     SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
229     if (pViewFrame != NULL)
230     {
231         SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
232         if (pDispatcher != NULL &&  pEvent != NULL)
233         {
234             sal_uInt16 nIndex = PreviewValueSet::GetItemId (pEvent->GetPosPixel());
235             if (nIndex > 0)
236                 PreviewValueSet::SelectItem (nIndex);
237         }
238     }
239     return 0;
240 }
241 
242 
243 
244 
245 void MasterPagesSelector::Command (const CommandEvent& rEvent)
246 {
247     switch (rEvent.GetCommand())
248     {
249         case COMMAND_CONTEXTMENU:
250         {
251             // Use the currently selected item and show the popup menu in its
252             // center.
253             const sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId();
254             if (nIndex > 0)
255             {
256                 // The position of the upper left corner of the context menu is
257                 // taken either from the mouse position (when the command was sent
258                 // as reaction to a right click) or in the center of the selected
259                 // item (when the command was sent as reaction to Shift+F10.)
260                 Point aPosition (rEvent.GetMousePosPixel());
261                 if ( ! rEvent.IsMouseEvent())
262                 {
263                     Rectangle aBBox (PreviewValueSet::GetItemRect(nIndex));
264                     aPosition = aBBox.Center();
265                 }
266 
267                 // Setup the menu.
268                 ::boost::scoped_ptr<PopupMenu> pMenu (new PopupMenu(GetContextMenuResId()));
269                 FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
270                 if (pMenuWindow != NULL)
271                     pMenuWindow->SetPopupModeFlags(
272                         pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE);
273                 pMenu->SetSelectHdl(LINK(this, MasterPagesSelector, OnMenuItemSelected));
274 
275                 ProcessPopupMenu(*pMenu);
276 
277                 // Show the menu.
278                 pMenu->Execute(this, Rectangle(aPosition,Size(1,1)), POPUPMENU_EXECUTE_DOWN);
279             }
280             break;
281         }
282     }
283 }
284 
285 
286 
287 
288 void MasterPagesSelector::ProcessPopupMenu (Menu& rMenu)
289 {
290     // Disable some entries.
291     if (mpContainer->GetPreviewSize() == MasterPageContainer::SMALL)
292         rMenu.EnableItem(SID_TP_SHOW_SMALL_PREVIEW, sal_False);
293     else
294         rMenu.EnableItem(SID_TP_SHOW_LARGE_PREVIEW, sal_False);
295 }
296 
297 
298 
299 
300 IMPL_LINK(MasterPagesSelector, OnMenuItemSelected, Menu*, pMenu)
301 {
302     if (pMenu == NULL)
303     {
304         OSL_ENSURE(pMenu!=NULL, "MasterPagesSelector::OnMenuItemSelected: illegal menu!");
305         return 0;
306     }
307 
308     pMenu->Deactivate();
309     ExecuteCommand(pMenu->GetCurItemId());
310     return 0;
311 }
312 
313 
314 
315 
316 void MasterPagesSelector::ExecuteCommand (const sal_Int32 nCommandId)
317 {
318 	switch (nCommandId)
319     {
320         case SID_TP_APPLY_TO_ALL_SLIDES:
321             mrBase.SetBusyState (true);
322             AssignMasterPageToAllSlides (GetSelectedMasterPage());
323             mrBase.SetBusyState (false);
324             break;
325 
326         case SID_TP_APPLY_TO_SELECTED_SLIDES:
327             mrBase.SetBusyState (true);
328             AssignMasterPageToSelectedSlides (GetSelectedMasterPage());
329             mrBase.SetBusyState (false);
330             break;
331 
332         case SID_TP_USE_FOR_NEW_PRESENTATIONS:
333             DBG_ASSERT (false,
334                 "Using slides as default for new presentations"
335                 " is not yet implemented");
336             break;
337 
338         case SID_TP_SHOW_SMALL_PREVIEW:
339         case SID_TP_SHOW_LARGE_PREVIEW:
340         {
341             mrBase.SetBusyState (true);
342             mpContainer->SetPreviewSize(
343                 nCommandId==SID_TP_SHOW_SMALL_PREVIEW
344                 ? MasterPageContainer::SMALL
345                 : MasterPageContainer::LARGE);
346             mrBase.SetBusyState (false);
347             if (mxSidebar.is())
348                 mxSidebar->requestLayout();
349             break;
350         }
351 
352         case SID_TP_EDIT_MASTER:
353         {
354             using namespace ::com::sun::star;
355             uno::Reference<drawing::XDrawPage> xSelectedMaster (
356                 GetSelectedMasterPage()->getUnoPage(), uno::UNO_QUERY);
357             SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
358             if (pViewFrame != NULL && xSelectedMaster.is())
359             {
360                 SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
361                 if (pDispatcher != NULL)
362                 {
363                     sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId();
364                     pDispatcher->Execute(SID_MASTERPAGE, SFX_CALLMODE_SYNCHRON);
365                     PreviewValueSet::SelectItem (nIndex);
366                     mrBase.GetDrawController().setCurrentPage(xSelectedMaster);
367                 }
368             }
369             break;
370         }
371 
372         case SID_CUT:
373         case SID_COPY:
374         case SID_PASTE:
375             // Cut, copy, and paste are not supported and thus are ignored.
376             break;
377     }
378 }
379 
380 
381 
382 
383 IMPL_LINK(MasterPagesSelector, ContainerChangeListener, MasterPageContainerChangeEvent*, pEvent)
384 {
385     if (pEvent)
386         NotifyContainerChangeEvent(*pEvent);
387     return 0;
388 }
389 
390 
391 
392 
393 SdPage* MasterPagesSelector::GetSelectedMasterPage (void)
394 {
395     const ::osl::MutexGuard aGuard (maMutex);
396 
397     SdPage* pMasterPage = NULL;
398     sal_uInt16 nIndex = PreviewValueSet::GetSelectItemId();
399     UserData* pData = GetUserData(nIndex);
400     if (pData != NULL)
401     {
402         pMasterPage = mpContainer->GetPageObjectForToken(pData->second);
403     }
404     return pMasterPage;
405 }
406 
407 
408 
409 
410 /** Assemble a list of all slides of the document and pass it to
411     AssignMasterPageToPageList().
412 */
413 void MasterPagesSelector::AssignMasterPageToAllSlides (SdPage* pMasterPage)
414 {
415     do
416     {
417         if (pMasterPage == NULL)
418             break;
419 
420         sal_uInt16 nPageCount = mrDocument.GetSdPageCount(PK_STANDARD);
421         if (nPageCount == 0)
422             break;
423 
424         // Get a list of all pages.  As a little optimization we only
425         // include pages that do not already have the given master page
426         // assigned.
427         String sFullLayoutName (pMasterPage->GetLayoutName());
428         ::sd::slidesorter::SharedPageSelection pPageList (
429             new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
430         for (sal_uInt16 nPageIndex=0; nPageIndex<nPageCount; nPageIndex++)
431         {
432             SdPage* pPage = mrDocument.GetSdPage (nPageIndex, PK_STANDARD);
433             if (pPage != NULL
434                 && pPage->GetLayoutName().CompareTo(sFullLayoutName)!=0)
435             {
436                 pPageList->push_back (pPage);
437             }
438         }
439 
440         AssignMasterPageToPageList(pMasterPage, pPageList);
441     }
442     while (false);
443 }
444 
445 
446 
447 
448 /** Assemble a list of the currently selected slides (selected in a visible
449     slide sorter) and pass it to AssignMasterPageToPageList().
450 */
451 void MasterPagesSelector::AssignMasterPageToSelectedSlides (
452     SdPage* pMasterPage)
453 {
454     do
455     {
456         using namespace ::std;
457         using namespace ::sd::slidesorter;
458         using namespace ::sd::slidesorter::controller;
459 
460         if (pMasterPage == NULL)
461             break;
462 
463         // Find a visible slide sorter.
464         SlideSorterViewShell* pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
465         if (pSlideSorter == NULL)
466             break;
467 
468         // Get a list of selected pages.
469         ::sd::slidesorter::SharedPageSelection pPageSelection = pSlideSorter->GetPageSelection();
470         if (pPageSelection->empty())
471             break;
472 
473         AssignMasterPageToPageList(pMasterPage, pPageSelection);
474 
475         // Restore the previous selection.
476         pSlideSorter->SetPageSelection(pPageSelection);
477     }
478     while (false);
479 }
480 
481 
482 
483 
484 void MasterPagesSelector::AssignMasterPageToPageList (
485     SdPage* pMasterPage,
486     const ::sd::slidesorter::SharedPageSelection& rPageList)
487 {
488     DocumentHelper::AssignMasterPageToPageList(mrDocument, pMasterPage, rPageList);
489 }
490 
491 
492 
493 
494 void MasterPagesSelector::NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent)
495 {
496     const ::osl::MutexGuard aGuard (maMutex);
497 
498     switch (rEvent.meEventType)
499     {
500         case MasterPageContainerChangeEvent::SIZE_CHANGED:
501             PreviewValueSet::SetPreviewSize(mpContainer->GetPreviewSizePixel());
502             UpdateAllPreviews();
503             break;
504 
505         case MasterPageContainerChangeEvent::PREVIEW_CHANGED:
506         {
507             int nIndex (GetIndexForToken(rEvent.maChildToken));
508             if (nIndex >= 0)
509             {
510                 PreviewValueSet::SetItemImage (
511                     (sal_uInt16)nIndex,
512                     mpContainer->GetPreviewForToken(rEvent.maChildToken));
513                 PreviewValueSet::Invalidate(PreviewValueSet::GetItemRect((sal_uInt16)nIndex));
514             }
515         }
516         break;
517 
518         case MasterPageContainerChangeEvent::DATA_CHANGED:
519         {
520             InvalidateItem(rEvent.maChildToken);
521             Fill();
522         }
523         break;
524 
525 		default:
526 			break;
527    }
528 }
529 
530 
531 
532 
533 MasterPagesSelector::UserData* MasterPagesSelector::CreateUserData (
534     int nIndex,
535     MasterPageContainer::Token aToken) const
536 {
537     return new UserData(nIndex,aToken);
538 }
539 
540 
541 
542 
543 MasterPagesSelector::UserData* MasterPagesSelector::GetUserData (int nIndex) const
544 {
545     const ::osl::MutexGuard aGuard (maMutex);
546 
547     if (nIndex>0 && nIndex<=PreviewValueSet::GetItemCount())
548         return reinterpret_cast<UserData*>(PreviewValueSet::GetItemData((sal_uInt16)nIndex));
549     else
550         return NULL;
551 }
552 
553 
554 
555 
556 void MasterPagesSelector::SetUserData (int nIndex, UserData* pData)
557 {
558     const ::osl::MutexGuard aGuard (maMutex);
559 
560     if (nIndex>0 && nIndex<=PreviewValueSet::GetItemCount())
561     {
562         UserData* pOldData = GetUserData(nIndex);
563         if (pOldData!=NULL && pOldData!=pData)
564             delete pOldData;
565         PreviewValueSet::SetItemData((sal_uInt16)nIndex, pData);
566     }
567 }
568 
569 
570 
571 
572 bool MasterPagesSelector::IsResizable (void)
573 {
574     return false;
575 }
576 
577 
578 
579 
580 ::Window* MasterPagesSelector::GetWindow (void)
581 {
582     return this;
583 }
584 
585 
586 
587 
588 sal_Int32 MasterPagesSelector::GetMinimumWidth (void)
589 {
590     return mpContainer->GetPreviewSizePixel().Width() + 2*3;
591 }
592 
593 
594 
595 
596 void MasterPagesSelector::UpdateSelection (void)
597 {
598 }
599 
600 
601 
602 
603 void MasterPagesSelector::SetItem (
604     sal_uInt16 nIndex,
605     MasterPageContainer::Token aToken)
606 {
607     const ::osl::MutexGuard aGuard (maMutex);
608 
609     RemoveTokenToIndexEntry(nIndex,aToken);
610 
611     if (nIndex > 0)
612     {
613         if (aToken != MasterPageContainer::NIL_TOKEN)
614         {
615             Image aPreview (mpContainer->GetPreviewForToken(aToken));
616             MasterPageContainer::PreviewState eState (mpContainer->GetPreviewState(aToken));
617 
618             if (aPreview.GetSizePixel().Width()>0)
619             {
620                 if (PreviewValueSet::GetItemPos(nIndex) != VALUESET_ITEM_NOTFOUND)
621                 {
622                     PreviewValueSet::SetItemImage(nIndex,aPreview);
623                     PreviewValueSet::SetItemText(nIndex, mpContainer->GetPageNameForToken(aToken));
624                 }
625                 else
626                 {
627                     PreviewValueSet::InsertItem (
628                         nIndex,
629                         aPreview,
630                         mpContainer->GetPageNameForToken(aToken),
631                         nIndex);
632                 }
633                 SetUserData(nIndex, CreateUserData(nIndex,aToken));
634 
635                 AddTokenToIndexEntry(nIndex,aToken);
636             }
637 
638             if (eState == MasterPageContainer::PS_CREATABLE)
639                 mpContainer->RequestPreview(aToken);
640         }
641         else
642         {
643             PreviewValueSet::RemoveItem(nIndex);
644         }
645     }
646 
647 }
648 
649 
650 
651 
652 void MasterPagesSelector::AddTokenToIndexEntry (
653     sal_uInt16 nIndex,
654     MasterPageContainer::Token aToken)
655 {
656     const ::osl::MutexGuard aGuard (maMutex);
657 
658     maTokenToValueSetIndex[aToken] = nIndex;
659 }
660 
661 
662 
663 
664 void MasterPagesSelector::RemoveTokenToIndexEntry (
665     sal_uInt16 nIndex,
666     MasterPageContainer::Token aNewToken)
667 {
668     const ::osl::MutexGuard aGuard (maMutex);
669 
670     UserData* pData = GetUserData(nIndex);
671     if (pData != NULL)
672     {
673         // Get the token that the index pointed to previously.
674         MasterPageContainer::Token aOldToken (pData->second);
675 
676         if (aNewToken != aOldToken
677             && nIndex == GetIndexForToken(aOldToken))
678         {
679             maTokenToValueSetIndex[aOldToken] = 0;
680         }
681     }
682 }
683 
684 
685 
686 
687 void MasterPagesSelector::InvalidatePreview (const SdPage* pPage)
688 {
689     const ::osl::MutexGuard aGuard (maMutex);
690 
691     for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
692     {
693         UserData* pData = GetUserData(nIndex);
694         if (pData != NULL)
695         {
696             MasterPageContainer::Token aToken (pData->second);
697             if (pPage == mpContainer->GetPageObjectForToken(aToken,false))
698             {
699                 mpContainer->InvalidatePreview(aToken);
700                 mpContainer->RequestPreview(aToken);
701                 break;
702             }
703         }
704     }
705 }
706 
707 void MasterPagesSelector::UpdateAllPreviews (void)
708 {
709     const ::osl::MutexGuard aGuard (maMutex);
710 
711     for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
712     {
713         UserData* pData = GetUserData(nIndex);
714         if (pData != NULL)
715         {
716             MasterPageContainer::Token aToken (pData->second);
717             PreviewValueSet::SetItemImage(
718                 nIndex,
719                 mpContainer->GetPreviewForToken(aToken));
720             if (mpContainer->GetPreviewState(aToken) == MasterPageContainer::PS_CREATABLE)
721                 mpContainer->RequestPreview(aToken);
722         }
723     }
724     PreviewValueSet::Rearrange(true);
725 }
726 
727 
728 
729 
730 void MasterPagesSelector::ClearPageSet (void)
731 {
732     const ::osl::MutexGuard aGuard (maMutex);
733 
734     for (sal_uInt16 nIndex=1; nIndex<=PreviewValueSet::GetItemCount(); nIndex++)
735     {
736         UserData* pData = GetUserData(nIndex);
737         if (pData != NULL)
738             delete pData;
739     }
740     PreviewValueSet::Clear();
741 }
742 
743 
744 
745 
746 void MasterPagesSelector::SetHelpId( const rtl::OString& aId )
747 {
748     const ::osl::MutexGuard aGuard (maMutex);
749 
750 	PreviewValueSet::SetHelpId( aId );
751 }
752 
753 
754 
755 
756 sal_Int32 MasterPagesSelector::GetIndexForToken (MasterPageContainer::Token aToken) const
757 {
758     const ::osl::MutexGuard aGuard (maMutex);
759 
760     TokenToValueSetIndex::const_iterator iIndex (maTokenToValueSetIndex.find(aToken));
761     if (iIndex != maTokenToValueSetIndex.end())
762         return iIndex->second;
763     else
764         return -1;
765 }
766 
767 
768 
769 
770 void MasterPagesSelector::Clear (void)
771 {
772     const ::osl::MutexGuard aGuard (maMutex);
773 
774     ClearPageSet();
775 }
776 
777 
778 
779 
780 void MasterPagesSelector::InvalidateItem (MasterPageContainer::Token aToken)
781 {
782     const ::osl::MutexGuard aGuard (maMutex);
783 
784     ItemList::iterator iItem;
785     for (iItem=maCurrentItemList.begin(); iItem!=maCurrentItemList.end(); ++iItem)
786     {
787         if (*iItem == aToken)
788         {
789             *iItem = MasterPageContainer::NIL_TOKEN;
790             break;
791         }
792     }
793 }
794 
795 
796 
797 
798 void MasterPagesSelector::UpdateItemList (::std::auto_ptr<ItemList> pNewItemList)
799 {
800     const ::osl::MutexGuard aGuard (maMutex);
801 
802     ItemList::const_iterator iNewItem (pNewItemList->begin());
803     ItemList::const_iterator iCurrentItem (maCurrentItemList.begin());
804     ItemList::const_iterator iNewEnd (pNewItemList->end());
805     ItemList::const_iterator iCurrentEnd (maCurrentItemList.end());
806     sal_uInt16 nIndex (1);
807 
808     // Update existing items.
809     for ( ; iNewItem!=iNewEnd && iCurrentItem!=iCurrentEnd; ++iNewItem, ++iCurrentItem,++nIndex)
810     {
811         if (*iNewItem != *iCurrentItem)
812         {
813             SetItem(nIndex,*iNewItem);
814         }
815     }
816 
817     // Append new items.
818     for ( ; iNewItem!=iNewEnd; ++iNewItem,++nIndex)
819     {
820         SetItem(nIndex,*iNewItem);
821     }
822 
823     // Remove trailing items.
824     for ( ; iCurrentItem!=iCurrentEnd; ++iCurrentItem,++nIndex)
825     {
826         SetItem(nIndex,MasterPageContainer::NIL_TOKEN);
827     }
828 
829     maCurrentItemList.swap(*pNewItemList);
830 
831     PreviewValueSet::Rearrange();
832     if (mxSidebar.is())
833         mxSidebar->requestLayout();
834 }
835 
836 
837 
838 
839 css::ui::LayoutSize MasterPagesSelector::GetHeightForWidth (const sal_Int32 nWidth)
840 {
841     const sal_Int32 nHeight (GetPreferredHeight(nWidth));
842     return css::ui::LayoutSize(nHeight,nHeight,nHeight);
843 }
844 
845 } } // end of namespace sd::sidebar
846