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