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