xref: /AOO41X/main/sd/source/ui/sidebar/LayoutMenu.cxx (revision d5370dc8b91641fa460c79c207c7018af41d7460)
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 "LayoutMenu.hxx"
25 
26 #include "SidebarShellManager.hxx"
27 #include "app.hrc"
28 #include "drawdoc.hxx"
29 #include "framework/FrameworkHelper.hxx"
30 #include "glob.hrc"
31 #include "glob.hxx"
32 #include "helpids.h"
33 #include "pres.hxx"
34 #include "res_bmp.hrc"
35 #include "sdpage.hxx"
36 #include "sdresid.hxx"
37 #include "strings.hrc"
38 #include "tools/SlotStateListener.hxx"
39 #include "DrawController.hxx"
40 #include "DrawDocShell.hxx"
41 #include "DrawViewShell.hxx"
42 #include "EventMultiplexer.hxx"
43 #include "SlideSorterViewShell.hxx"
44 #include "ViewShellBase.hxx"
45 
46 #include <comphelper/processfactory.hxx>
47 #include <sfx2/app.hxx>
48 #include <sfx2/dispatch.hxx>
49 #include <sfx2/objface.hxx>
50 #include <sfx2/request.hxx>
51 #include <sfx2/viewfrm.hxx>
52 #include <svl/languageoptions.hxx>
53 #include <vcl/image.hxx>
54 #include <vcl/floatwin.hxx>
55 
56 #include <com/sun/star/frame/XController.hpp>
57 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
58 #include <com/sun/star/drawing/framework/XView.hpp>
59 #include <com/sun/star/drawing/framework/ResourceId.hpp>
60 
61 #include <vector>
62 #include <memory>
63 
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::text;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::drawing::framework;
68 using namespace ::sd::slidesorter;
69 using ::sd::framework::FrameworkHelper;
70 
71 namespace sd { namespace sidebar {
72 
73 
74 
75 struct snewfoil_value_info
76 {
77     sal_uInt16 mnBmpResId;
78     sal_uInt16 mnHCBmpResId;
79     sal_uInt16 mnStrResId;
80     WritingMode meWritingMode;
81     AutoLayout maAutoLayout;
82 };
83 
84 static snewfoil_value_info notes[] =
85 {
86     {BMP_FOILN_01, BMP_FOILN_01_H, STR_AUTOLAYOUT_NOTES, WritingMode_LR_TB,
87      AUTOLAYOUT_NOTES},
88     {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE},
89 };
90 
91 static snewfoil_value_info handout[] =
92 {
93     {BMP_FOILH_01, BMP_FOILH_01_H, STR_AUTOLAYOUT_HANDOUT1, WritingMode_LR_TB,
94      AUTOLAYOUT_HANDOUT1},
95     {BMP_FOILH_02, BMP_FOILH_02_H, STR_AUTOLAYOUT_HANDOUT2, WritingMode_LR_TB,
96      AUTOLAYOUT_HANDOUT2},
97     {BMP_FOILH_03, BMP_FOILH_03_H, STR_AUTOLAYOUT_HANDOUT3, WritingMode_LR_TB,
98      AUTOLAYOUT_HANDOUT3},
99     {BMP_FOILH_04, BMP_FOILH_04_H, STR_AUTOLAYOUT_HANDOUT4, WritingMode_LR_TB,
100      AUTOLAYOUT_HANDOUT4},
101     {BMP_FOILH_06, BMP_FOILH_06_H, STR_AUTOLAYOUT_HANDOUT6, WritingMode_LR_TB,
102      AUTOLAYOUT_HANDOUT6},
103     {BMP_FOILH_09, BMP_FOILH_09_H, STR_AUTOLAYOUT_HANDOUT9, WritingMode_LR_TB,
104      AUTOLAYOUT_HANDOUT9},
105     {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE},
106 };
107 
108 static snewfoil_value_info standard[] =
109 {
110     {BMP_LAYOUT_EMPTY, BMP_LAYOUT_EMPTY_H, STR_AUTOLAYOUT_NONE, WritingMode_LR_TB,        AUTOLAYOUT_NONE},
111 	{BMP_LAYOUT_HEAD03, BMP_LAYOUT_HEAD03_H, STR_AUTOLAYOUT_TITLE, WritingMode_LR_TB,       AUTOLAYOUT_TITLE},
112     {BMP_LAYOUT_HEAD02, BMP_LAYOUT_HEAD02_H, STR_AUTOLAYOUT_CONTENT, WritingMode_LR_TB,        AUTOLAYOUT_ENUM},
113 	{BMP_LAYOUT_HEAD02A, BMP_LAYOUT_HEAD02A_H, STR_AUTOLAYOUT_2CONTENT, WritingMode_LR_TB,       AUTOLAYOUT_2TEXT},
114 	{BMP_LAYOUT_HEAD01, BMP_LAYOUT_HEAD01_H, STR_AUTOLAYOUT_ONLY_TITLE, WritingMode_LR_TB,  AUTOLAYOUT_ONLY_TITLE},
115 	{BMP_LAYOUT_TEXTONLY, BMP_LAYOUT_TEXTONLY_H, STR_AUTOLAYOUT_ONLY_TEXT, WritingMode_LR_TB,   AUTOLAYOUT_ONLY_TEXT},
116     {BMP_LAYOUT_HEAD03B, BMP_LAYOUT_HEAD03B_H, STR_AUTOLAYOUT_2CONTENT_CONTENT, WritingMode_LR_TB,    AUTOLAYOUT_2OBJTEXT},
117 	{BMP_LAYOUT_HEAD03C, BMP_LAYOUT_HEAD03C_H, STR_AUTOLAYOUT_CONTENT_2CONTENT, WritingMode_LR_TB,    AUTOLAYOUT_TEXT2OBJ},
118 	{BMP_LAYOUT_HEAD03A, BMP_LAYOUT_HEAD03A_H, STR_AUTOLAYOUT_2CONTENT_OVER_CONTENT,WritingMode_LR_TB, AUTOLAYOUT_2OBJOVERTEXT},
119 	{BMP_LAYOUT_HEAD02B, BMP_LAYOUT_HEAD02B_H, STR_AUTOLAYOUT_CONTENT_OVER_CONTENT, WritingMode_LR_TB, AUTOLAYOUT_OBJOVERTEXT},
120     {BMP_LAYOUT_HEAD04, BMP_LAYOUT_HEAD04_H, STR_AUTOLAYOUT_4CONTENT, WritingMode_LR_TB,        AUTOLAYOUT_4OBJ},
121 	{BMP_LAYOUT_HEAD06, BMP_LAYOUT_HEAD06_H, STR_AUTOLAYOUT_6CONTENT, WritingMode_LR_TB,    AUTOLAYOUT_6CLIPART},
122 
123 	// vertical
124     {BMP_LAYOUT_VERTICAL02, BMP_LAYOUT_VERTICAL02_H, STR_AL_VERT_TITLE_TEXT_CHART, WritingMode_TB_RL,AUTOLAYOUT_VERTICAL_TITLE_TEXT_CHART},
125     {BMP_LAYOUT_VERTICAL01, BMP_LAYOUT_VERTICAL01_H, STR_AL_VERT_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_VERTICAL_TITLE_VERTICAL_OUTLINE},
126     {BMP_LAYOUT_HEAD02, BMP_LAYOUT_HEAD02_H, STR_AL_TITLE_VERT_OUTLINE, WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE},
127     {BMP_LAYOUT_HEAD02A, BMP_LAYOUT_HEAD02A_H, STR_AL_TITLE_VERT_OUTLINE_CLIPART,   WritingMode_TB_RL, AUTOLAYOUT_TITLE_VERTICAL_OUTLINE_CLIPART},
128     {0, 0, 0, WritingMode_LR_TB, AUTOLAYOUT_NONE}
129 };
130 
131 
132 
133 
134 LayoutMenu::LayoutMenu (
135     ::Window* pParent,
136     ViewShellBase& rViewShellBase,
137     const cssu::Reference<css::ui::XSidebar>& rxSidebar)
138     : ValueSet (pParent),
139       DragSourceHelper(this),
140       DropTargetHelper(this),
141       mrBase(rViewShellBase),
142       mbUseOwnScrollBar(false),
143       mnPreferredColumnCount(3),
144       mxListener(NULL),
145       mbSelectionUpdatePending(true),
146       mbIsMainViewChangePending(false),
147       mxSidebar(rxSidebar),
148       mbIsDisposed(false)
149 {
150     implConstruct( *mrBase.GetDocument()->GetDocSh() );
151     OSL_TRACE("created LayoutMenu at %x", this);
152 
153 #ifdef DEBUG
154     SetText(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sd:LayoutMenu")));
155 #endif
156 }
157 
158 
159 
160 
161 void LayoutMenu::implConstruct( DrawDocShell& rDocumentShell )
162 {
163     OSL_ENSURE( mrBase.GetDocument()->GetDocSh() == &rDocumentShell,
164         "LayoutMenu::implConstruct: hmm?" );
165     // if this fires, then my assumption that the rDocumentShell parameter to our first ctor is superfluous ...
166 
167 	SetStyle (
168         ( GetStyle()  & ~(WB_ITEMBORDER) )
169         | WB_TABSTOP
170         | WB_NO_DIRECTSELECT
171         );
172     if (mbUseOwnScrollBar)
173         SetStyle (GetStyle() | WB_VSCROLL);
174 	SetExtraSpacing(2);
175 	SetSelectHdl (LINK(this, LayoutMenu, ClickHandler));
176     InvalidateContent();
177 
178     Link aEventListenerLink (LINK(this,LayoutMenu,EventMultiplexerListener));
179     mrBase.GetEventMultiplexer()->AddEventListener(aEventListenerLink,
180         ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE
181         | ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION
182         | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
183         | ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
184         | ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED
185         | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL
186         | ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER);
187 
188     Window::SetHelpId(HID_SD_TASK_PANE_PREVIEW_LAYOUTS);
189     SetAccessibleName(SdResId(STR_TASKPANEL_LAYOUT_MENU_TITLE));
190 
191     Link aStateChangeLink (LINK(this,LayoutMenu,StateChangeHandler));
192     mxListener = new ::sd::tools::SlotStateListener(
193         aStateChangeLink,
194         Reference<frame::XDispatchProvider>(mrBase.GetController()->getFrame(), UNO_QUERY),
195         ::rtl::OUString::createFromAscii(".uno:VerticalTextState"));
196 
197     SetSizePixel(GetParent()->GetSizePixel());
198     Link aWindowEventHandlerLink (LINK(this,LayoutMenu,WindowEventHandler));
199     GetParent()->AddEventListener(aWindowEventHandlerLink);
200 }
201 
202 
203 
204 
205 LayoutMenu::~LayoutMenu (void)
206 {
207     OSL_TRACE("destroying LayoutMenu at %x", this);
208     Dispose();
209 }
210 
211 
212 
213 
214 void LayoutMenu::Dispose (void)
215 {
216     if (mbIsDisposed)
217         return;
218 
219     OSL_TRACE("disposing LayoutMenu at %x", this);
220 
221     mbIsDisposed = true;
222 
223     Reference<lang::XComponent> xComponent (mxListener, UNO_QUERY);
224     if (xComponent.is())
225         xComponent->dispose();
226 
227     Clear();
228     Link aLink (LINK(this,LayoutMenu,EventMultiplexerListener));
229     mrBase.GetEventMultiplexer()->RemoveEventListener (aLink);
230 
231     Link aWindowEventHandlerLink (LINK(this,LayoutMenu,WindowEventHandler));
232     GetParent()->RemoveEventListener(aWindowEventHandlerLink);
233 }
234 
235 
236 
237 
238 AutoLayout LayoutMenu::GetSelectedAutoLayout (void)
239 {
240     AutoLayout aResult = AUTOLAYOUT_NONE;
241 
242     if ( ! IsNoSelection() && GetSelectItemId()!=0)
243     {
244         AutoLayout* pLayout = static_cast<AutoLayout*>(GetItemData(GetSelectItemId()));
245         if (pLayout != NULL)
246             aResult = *pLayout;
247     }
248 
249     return aResult;
250 }
251 
252 
253 
254 
255 /** The preferred size depends on the preferred number of columns, the
256     number of items, and the size of the items.
257 */
258 Size LayoutMenu::GetPreferredSize (void)
259 {
260     Size aItemSize = CalcItemSizePixel (Size());
261     Size aPreferredWindowSize = CalcWindowSizePixel (
262         aItemSize,
263          (sal_uInt16)mnPreferredColumnCount,
264         (sal_uInt16)CalculateRowCount (aItemSize,mnPreferredColumnCount));
265     return aPreferredWindowSize;
266 }
267 
268 
269 
270 
271 sal_Int32 LayoutMenu::GetPreferredWidth (sal_Int32 nHeight)
272 {
273     sal_Int32 nPreferredWidth = 100;
274     if (GetItemCount() > 0)
275     {
276         Image aImage = GetItemImage(GetItemId(0));
277         Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
278         if (nHeight>0 && aItemSize.Height()>0)
279         {
280             int nRowCount = nHeight / aItemSize.Height();
281             if (nRowCount <= 0)
282                 nRowCount = 1;
283             int nColumnCount = (GetItemCount() + nRowCount-1) / nRowCount;
284             nPreferredWidth = nColumnCount * aItemSize.Width();
285         }
286     }
287 
288     return nPreferredWidth;
289 }
290 
291 
292 
293 
294 ui::LayoutSize LayoutMenu::GetHeightForWidth (const sal_Int32 nWidth)
295 {
296     sal_Int32 nPreferredHeight = 200;
297     if ( ! mbUseOwnScrollBar && GetItemCount()>0)
298     {
299         Image aImage = GetItemImage(GetItemId(0));
300         Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
301         if (nWidth>0 && aItemSize.Width()>0)
302         {
303             aItemSize.Width() += 8;
304             aItemSize.Height() += 8;
305             int nColumnCount = nWidth / aItemSize.Width();
306             if (nColumnCount <= 0)
307                 nColumnCount = 1;
308             else if (nColumnCount > 4)
309                 nColumnCount = 4;
310             int nRowCount = (GetItemCount() + nColumnCount-1) / nColumnCount;
311             nPreferredHeight = nRowCount * aItemSize.Height();
312         }
313     }
314     return ui::LayoutSize(nPreferredHeight,nPreferredHeight,nPreferredHeight);
315 }
316 
317 
318 
319 
320 sal_Int32 LayoutMenu::GetMinimumWidth (void)
321 {
322     sal_Int32 nMinimumWidth = 0;
323     if (GetItemCount()>0)
324     {
325         Image aImage = GetItemImage(GetItemId(0));
326         Size aItemSize = CalcItemSizePixel (aImage.GetSizePixel());
327         nMinimumWidth = aItemSize.Width();
328     }
329     return nMinimumWidth;
330 }
331 
332 
333 
334 
335 void LayoutMenu::UpdateEnabledState (const MasterMode eMode)
336 {
337     bool bIsEnabled (false);
338 
339     ::boost::shared_ptr<ViewShell> pMainViewShell (mrBase.GetMainViewShell());
340     if (pMainViewShell)
341     {
342         switch (pMainViewShell->GetShellType())
343         {
344             case ViewShell::ST_NONE:
345             case ViewShell::ST_OUTLINE:
346             case ViewShell::ST_PRESENTATION:
347             case ViewShell::ST_SIDEBAR:
348                 // The complete task pane is disabled for these values or
349                 // not even visible.  Disabling the LayoutMenu would be
350                 // logical but unnecessary.  The main disadvantage is that
351                 // after re-enabling it (typically) another panel is
352                 // expanded.
353                 bIsEnabled = true;
354                 break;
355 
356             case ViewShell::ST_DRAW:
357             case ViewShell::ST_IMPRESS:
358             {
359                 switch (eMode)
360                 {
361                     case MM_UNKNOWN:
362                     {
363                         ::boost::shared_ptr<DrawViewShell> pDrawViewShell (
364                             ::boost::dynamic_pointer_cast<DrawViewShell>(pMainViewShell));
365                         if (pDrawViewShell)
366                             bIsEnabled = pDrawViewShell->GetEditMode() != EM_MASTERPAGE;
367                         break;
368                     }
369                     case MM_NORMAL:
370                         bIsEnabled = true;
371                         break;
372 
373                     case MM_MASTER:
374                         bIsEnabled = false;
375                         break;
376                 }
377                 break;
378             }
379 
380             case ViewShell::ST_HANDOUT:
381             case ViewShell::ST_NOTES:
382             case ViewShell::ST_SLIDE_SORTER:
383             default:
384                 bIsEnabled = true;
385                 break;
386         }
387     }
388 }
389 
390 
391 
392 
393 void LayoutMenu::Paint (const Rectangle& rRect)
394 {
395 	SetBackground (GetSettings().GetStyleSettings().GetWindowColor());
396 
397     if (mbSelectionUpdatePending)
398     {
399         mbSelectionUpdatePending = false;
400         UpdateSelection();
401     }
402     ValueSet::Paint (rRect);
403 
404 	SetBackground (Wallpaper());
405 }
406 
407 
408 
409 
410 void LayoutMenu::Resize (void)
411 {
412     Size aWindowSize = GetOutputSizePixel();
413     if (IsVisible() && aWindowSize.Width() > 0)
414     {
415         // Calculate the number of rows and columns.
416         if (GetItemCount() > 0)
417         {
418             Image aImage = GetItemImage(GetItemId(0));
419             Size aItemSize = CalcItemSizePixel (
420                 aImage.GetSizePixel());
421             aItemSize.Width() += 8;
422             aItemSize.Height() += 8;
423             int nColumnCount = aWindowSize.Width() / aItemSize.Width();
424             if (nColumnCount < 1)
425                 nColumnCount = 1;
426             else if (nColumnCount > 4)
427                 nColumnCount = 4;
428 
429             int nRowCount = CalculateRowCount (aItemSize, nColumnCount);
430 
431             SetColCount ((sal_uInt16)nColumnCount);
432             SetLineCount ((sal_uInt16)nRowCount);
433         }
434     }
435 
436     ValueSet::Resize ();
437 }
438 
439 
440 
441 
442 void LayoutMenu::MouseButtonDown (const MouseEvent& rEvent)
443 {
444     // As a preparation for the context menu the item under the mouse is
445     // selected.
446     if (rEvent.IsRight())
447     {
448         ReleaseMouse();
449         sal_uInt16 nIndex = GetItemId (rEvent.GetPosPixel());
450         if (nIndex > 0)
451             SelectItem(nIndex);
452     }
453 
454     ValueSet::MouseButtonDown (rEvent);
455 }
456 
457 
458 
459 /*
460 void LayoutMenu::GetState (SfxItemSet& rItemSet)
461 {
462     // Cut and paste is not supported.  The SID_(CUT,COPY,PASTE) entries
463     // therefore must not show up in the context menu.
464     rItemSet.DisableItem (SID_CUT);
465     rItemSet.DisableItem (SID_COPY);
466     rItemSet.DisableItem (SID_PASTE);
467 
468     // The SID_INSERTPAGE_LAYOUT_MENU slot depends on the SID_INSERTPAGE
469     // slot being supported elsewhere.
470     const SfxPoolItem* pItem = NULL;
471     const SfxItemState aState (
472         mrBase.GetViewFrame()->GetDispatcher()->QueryState(SID_INSERTPAGE, pItem));
473     if (aState == SFX_ITEM_DISABLED)
474         rItemSet.DisableItem(SID_INSERTPAGE_LAYOUT_MENU);
475 }
476 */
477 
478 
479 
480 void LayoutMenu::InsertPageWithLayout (AutoLayout aLayout)
481 {
482     ViewShell* pViewShell = mrBase.GetMainViewShell().get();
483     if (pViewShell == NULL)
484         return;
485 
486     SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
487     if (pViewFrame == NULL)
488         return;
489 
490     SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
491     if (pDispatcher == NULL)
492         return;
493 
494     // Call SID_INSERTPAGE with the right arguments.  This is because
495     // the popup menu can not call this slot with arguments directly.
496     SfxRequest aRequest (CreateRequest(SID_INSERTPAGE, aLayout));
497     if (aRequest.GetArgs() != NULL)
498     {
499         pDispatcher->Execute(
500             SID_INSERTPAGE,
501             SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
502             *aRequest.GetArgs());
503     }
504     UpdateSelection();
505 }
506 
507 
508 
509 
510 void LayoutMenu::InvalidateContent (void)
511 {
512     // The number of items may have changed.  Request a resize so that the
513     // vertical size of this control can be adapted.
514     //    RequestResize();
515 
516     // Throw away the current set and fill the menu anew according to the
517     // current settings (this includes the support for vertical writing.)
518     Fill();
519 
520     if (mxSidebar.is())
521         mxSidebar->requestLayout();
522 }
523 
524 
525 
526 
527 int LayoutMenu::CalculateRowCount (const Size&, int nColumnCount)
528 {
529     int nRowCount = 0;
530 
531     if (GetItemCount() > 0 && nColumnCount > 0)
532     {
533         nRowCount = (GetItemCount() + nColumnCount - 1) / nColumnCount;
534         //        nRowCount = GetOutputSizePixel().Height() / rItemSize.Height();
535         if (nRowCount < 1)
536             nRowCount = 1;
537     }
538 
539     return nRowCount;
540 }
541 
542 
543 
544 
545 IMPL_LINK(LayoutMenu, ClickHandler, ValueSet*, EMPTYARG)
546 {
547     AssignLayoutToSelectedSlides (GetSelectedAutoLayout());
548     return 0;
549 }
550 
551 
552 
553 
554 /** The specified layout is assigned to the current page of the view shell
555     in the center pane.
556 */
557 void LayoutMenu::AssignLayoutToSelectedSlides (AutoLayout aLayout)
558 {
559     using namespace ::sd::slidesorter;
560     using namespace ::sd::slidesorter::controller;
561 
562     do
563     {
564         // The view shell in the center pane has to be present.
565         ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
566         if (pMainViewShell == NULL)
567             break;
568 
569         // Determine if the current view is in an invalid master page mode.
570         // The handout view is always in master page mode and therefore not
571         // invalid.
572         bool bMasterPageMode (false);
573         switch (pMainViewShell->GetShellType())
574         {
575             case ViewShell::ST_NOTES:
576             case ViewShell::ST_IMPRESS:
577             {
578                 DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(pMainViewShell);
579                 if (pDrawViewShell != NULL)
580                     if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
581                         bMasterPageMode = true;
582             }
583 			default:
584 				break;
585         }
586         if (bMasterPageMode)
587             break;
588 
589         // Get a list of all selected slides and call the SID_MODIFYPAGE
590         // slot for all of them.
591 		::sd::slidesorter::SharedPageSelection pPageSelection;
592 
593         // Get a list of selected pages.
594         // First we try to obtain this list from a slide sorter.  This is
595         // possible only some of the view shells in the center pane.  When
596         // no valid slide sorter is available then ask the main view shell
597         // for its current page.
598         SlideSorterViewShell* pSlideSorter = NULL;
599         switch (pMainViewShell->GetShellType())
600         {
601             case ViewShell::ST_IMPRESS:
602             case ViewShell::ST_NOTES:
603             case ViewShell::ST_SLIDE_SORTER:
604                 pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
605                 break;
606 			default:
607 				break;
608         }
609 		if (pSlideSorter != NULL)
610 		{
611 			// There is a slide sorter visible so get the list of selected pages from it.
612             pPageSelection = pSlideSorter->GetPageSelection();
613 		}
614 
615 		if( (pSlideSorter == NULL) || (pPageSelection.get() == 0) || pPageSelection->empty() )
616 		{
617 			// No valid slide sorter available.  Ask the main view shell for
618 			// its current page.
619             pPageSelection.reset(new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
620             pPageSelection->push_back(pMainViewShell->GetActualPage());
621 		}
622 
623 
624 		if (pPageSelection->empty())
625 			break;
626 
627 		::std::vector<SdPage*>::iterator iPage;
628 		for (iPage=pPageSelection->begin(); iPage!=pPageSelection->end(); ++iPage)
629 			{
630 				if ((*iPage) == NULL)
631 					continue;
632 
633 				// Call the SID_ASSIGN_LAYOUT slot with all the necessary parameters.
634 				SfxRequest aRequest (mrBase.GetViewFrame(), SID_ASSIGN_LAYOUT);
635 				aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATPAGE, ((*iPage)->GetPageNum()-1)/2));
636 				aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
637 				pMainViewShell->ExecuteSlot (aRequest, sal_Bool(sal_False));
638 			}
639     }
640     while(false);
641 }
642 
643 
644 
645 
646 SfxRequest LayoutMenu::CreateRequest (
647     sal_uInt16 nSlotId,
648     AutoLayout aLayout)
649 {
650     SfxRequest aRequest (mrBase.GetViewFrame(), nSlotId);
651 
652     do
653     {
654         SdrLayerAdmin& rLayerAdmin (mrBase.GetDocument()->GetLayerAdmin());
655         sal_uInt8 aBackground (rLayerAdmin.GetLayerID(
656             String(SdResId(STR_LAYER_BCKGRND)), sal_False));
657         sal_uInt8 aBackgroundObject (rLayerAdmin.GetLayerID(
658             String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False));
659         ViewShell* pViewShell = mrBase.GetMainViewShell().get();
660         if (pViewShell == NULL)
661             break;
662         SdPage* pPage = pViewShell->GetActualPage();
663         if (pPage == NULL)
664             break;
665 
666         SetOfByte aVisibleLayers (pPage->TRG_GetMasterPageVisibleLayers());
667 
668         aRequest.AppendItem(
669             SfxStringItem (ID_VAL_PAGENAME, String()));//pPage->GetName()));
670         aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
671         aRequest.AppendItem(
672             SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground)));
673         aRequest.AppendItem(
674             SfxBoolItem(
675                 ID_VAL_ISPAGEOBJ,
676                 aVisibleLayers.IsSet(aBackgroundObject)));
677     }
678     while (false);
679 
680     return aRequest;
681 }
682 
683 
684 
685 
686 void LayoutMenu::Fill (void)
687 {
688 	const bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
689 	SvtLanguageOptions aLanguageOptions;
690     sal_Bool bVertical = aLanguageOptions.IsVerticalTextEnabled();
691     SdDrawDocument* pDocument = mrBase.GetDocument();
692     sal_Bool bRightToLeft = (pDocument!=NULL
693         && pDocument->GetDefaultWritingMode() == WritingMode_RL_TB);
694 
695     // Get URL of the view in the center pane.
696     ::rtl::OUString sCenterPaneViewName;
697     try
698     {
699         Reference<XControllerManager> xControllerManager (
700             Reference<XWeak>(&mrBase.GetDrawController()), UNO_QUERY_THROW);
701         Reference<XResourceId> xPaneId (ResourceId::create(
702             ::comphelper::getProcessComponentContext(),
703             FrameworkHelper::msCenterPaneURL));
704         Reference<XView> xView (FrameworkHelper::Instance(mrBase)->GetView(xPaneId));
705         if (xView.is())
706             sCenterPaneViewName = xView->getResourceId()->getResourceURL();
707     }
708     catch (RuntimeException&)
709     {}
710 
711 	snewfoil_value_info* pInfo = NULL;
712     if (sCenterPaneViewName.equals(framework::FrameworkHelper::msNotesViewURL))
713     {
714         pInfo = notes;
715     }
716     else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msHandoutViewURL))
717     {
718         pInfo = handout;
719     }
720     else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msImpressViewURL)
721         || sCenterPaneViewName.equals(framework::FrameworkHelper::msSlideSorterURL))
722     {
723         pInfo = standard;
724     }
725     else
726     {
727         pInfo = NULL;
728 	}
729 
730     Clear();
731     int n = 0;
732 	for (sal_uInt16 i=1; pInfo!=NULL&&pInfo->mnBmpResId!=0; i++,pInfo++)
733 	{
734         if ((WritingMode_TB_RL != pInfo->meWritingMode) || bVertical)
735         {
736             BitmapEx aBmp (SdResId (bHighContrast
737                              ? pInfo->mnHCBmpResId
738                              : pInfo->mnBmpResId));
739 
740             if (bRightToLeft && (WritingMode_TB_RL != pInfo->meWritingMode))
741                 aBmp.Mirror (BMP_MIRROR_HORZ);
742 
743             InsertItem (i, aBmp, String (SdResId (pInfo->mnStrResId)));
744             SetItemData (i, new AutoLayout(pInfo->maAutoLayout));
745             n++;
746         }
747 	}
748 
749     mbSelectionUpdatePending = true;
750 }
751 
752 
753 
754 
755 void LayoutMenu::Clear (void)
756 {
757     for (sal_uInt16 nId=1; nId<=GetItemCount(); nId++)
758         delete static_cast<AutoLayout*>(GetItemData(nId));
759     ValueSet::Clear();
760 }
761 
762 
763 
764 void LayoutMenu::StartDrag (sal_Int8 , const Point& )
765 {
766 }
767 
768 
769 
770 
771 sal_Int8 LayoutMenu::AcceptDrop (const AcceptDropEvent& )
772 {
773     return 0;
774 }
775 
776 
777 
778 
779 sal_Int8 LayoutMenu::ExecuteDrop (const ExecuteDropEvent& )
780 {
781     return 0;
782 }
783 
784 
785 
786 
787 void LayoutMenu::Command (const CommandEvent& rEvent)
788 {
789     switch (rEvent.GetCommand())
790     {
791         case COMMAND_CONTEXTMENU:
792             if ( ! SD_MOD()->GetWaterCan())
793             {
794                 // Determine the position where to show the menu.
795                 Point aMenuPosition;
796                 if (rEvent.IsMouseEvent())
797                 {
798                     if (GetItemId(rEvent.GetMousePosPixel()) <= 0)
799                         return;
800                     aMenuPosition = rEvent.GetMousePosPixel();
801                 }
802                 else
803                 {
804                     if (GetSelectItemId() == (sal_uInt16)-1)
805                         return;
806                     Rectangle aBBox (GetItemRect(GetSelectItemId()));
807                     aMenuPosition = aBBox.Center();
808                 }
809 
810                 // Setup the menu.
811                 ::boost::shared_ptr<PopupMenu> pMenu (new PopupMenu(SdResId(RID_TASKPANE_LAYOUTMENU_POPUP)));
812                 FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
813                 if (pMenuWindow != NULL)
814                     pMenuWindow->SetPopupModeFlags(
815                         pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE);
816                 pMenu->SetSelectHdl(LINK(this, LayoutMenu, OnMenuItemSelected));
817 
818                 // Disable the SID_INSERTPAGE_LAYOUT_MENU item when
819                 // the document is read-only.
820                 const SfxPoolItem* pItem = NULL;
821                 const SfxItemState aState (
822                     mrBase.GetViewFrame()->GetDispatcher()->QueryState(SID_INSERTPAGE, pItem));
823                 if (aState == SFX_ITEM_DISABLED)
824                     pMenu->EnableItem(SID_INSERTPAGE_LAYOUT_MENU, sal_False);
825 
826                 // Show the menu.
827                 pMenu->Execute(this, Rectangle(aMenuPosition,Size(1,1)), POPUPMENU_EXECUTE_DOWN);
828             }
829             break;
830 
831         default:
832             ValueSet::Command(rEvent);
833             break;
834     }
835 }
836 
837 
838 
839 
840 IMPL_LINK(LayoutMenu, StateChangeHandler, ::rtl::OUString*, EMPTYARG)
841 {
842     InvalidateContent();
843     return 0;
844 }
845 
846 
847 
848 
849 IMPL_LINK(LayoutMenu, OnMenuItemSelected, Menu*, pMenu)
850 {
851     if (pMenu == NULL)
852     {
853         OSL_ENSURE(pMenu!=NULL, "LayoutMenu::OnMenuItemSelected: illegal menu!");
854         return 0;
855     }
856 
857     pMenu->Deactivate();
858     const sal_Int32 nIndex (pMenu->GetCurItemId());
859 
860     if (nIndex == SID_TP_APPLY_TO_SELECTED_SLIDES)
861     {
862         AssignLayoutToSelectedSlides(GetSelectedAutoLayout());
863     }
864     else if (nIndex == SID_INSERTPAGE_LAYOUT_MENU)
865     {
866         // Add arguments to this slot and forward it to the main view
867         // shell.
868         InsertPageWithLayout(GetSelectedAutoLayout());
869     }
870 
871     return 0;
872 }
873 
874 
875 
876 
877 void LayoutMenu::UpdateSelection (void)
878 {
879     bool bItemSelected = false;
880 
881     do
882     {
883         // Get current page of main view.
884         ViewShell* pViewShell = mrBase.GetMainViewShell().get();
885         if (pViewShell == NULL)
886             break;
887 
888         SdPage* pCurrentPage = pViewShell->getCurrentPage();
889         if (pCurrentPage == NULL)
890             break;
891 
892         // Get layout of current page.
893         AutoLayout aLayout (pCurrentPage->GetAutoLayout());
894         if (aLayout<AUTOLAYOUT__START || aLayout>AUTOLAYOUT__END)
895             break;
896 
897         // Find the entry of the menu for to the layout.
898         sal_uInt16 nItemCount (GetItemCount());
899         for (sal_uInt16 nId=1; nId<=nItemCount; nId++)
900         {
901             if (*static_cast<AutoLayout*>(GetItemData(nId)) == aLayout)
902             {
903                 SelectItem(nId);
904                 bItemSelected = true;
905                 break;
906             }
907         }
908     }
909     while (false);
910 
911     if ( ! bItemSelected)
912         SetNoSelection();
913 }
914 
915 
916 
917 
918 IMPL_LINK(LayoutMenu, EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*, pEvent)
919 {
920     switch (pEvent->meEventId)
921     {
922         case ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
923         case ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
924             if ( ! mbSelectionUpdatePending)
925                 UpdateSelection();
926             break;
927 
928         case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
929             mbIsMainViewChangePending = true;
930             UpdateEnabledState(MM_UNKNOWN);
931             break;
932 
933         case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
934             HideFocus();
935             break;
936 
937         case ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
938             if (mbIsMainViewChangePending)
939             {
940                 mbIsMainViewChangePending = false;
941                 InvalidateContent();
942             }
943             break;
944 
945         case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_NORMAL:
946             UpdateEnabledState(MM_NORMAL);
947             break;
948 
949         case ::sd::tools::EventMultiplexerEvent::EID_EDIT_MODE_MASTER:
950             UpdateEnabledState(MM_MASTER);
951             break;
952 
953         default:
954             /* Ignored */
955             break;
956     }
957 
958     return 0;
959 }
960 
961 
962 
963 
964 IMPL_LINK(LayoutMenu, WindowEventHandler, VclWindowEvent*, pEvent)
965 {
966     if (pEvent != NULL)
967     {
968         switch (pEvent->GetId())
969         {
970             case VCLEVENT_WINDOW_SHOW:
971             case VCLEVENT_WINDOW_RESIZE:
972                 SetSizePixel(GetParent()->GetSizePixel());
973                 return sal_True;
974 
975             default:
976                 return sal_False;
977         }
978 
979         const SfxSimpleHint* pSimpleHint = PTR_CAST(SfxSimpleHint, pEvent);
980         if (pSimpleHint != NULL
981             && pSimpleHint->GetId() == SFX_HINT_DYING)
982         {
983             return sal_True;
984         }
985     }
986 
987     return sal_False;
988 }
989 
990 
991 
992 
993 void LayoutMenu::DataChanged (const DataChangedEvent& rEvent)
994 {
995     Fill();
996     ValueSet::DataChanged(rEvent);
997 }
998 
999 
1000 
1001 
1002 
1003 } } // end of namespace ::sd::sidebar
1004