xref: /trunk/main/sd/source/ui/sidebar/LayoutMenu.cxx (revision 6dc7b748)
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 
LayoutMenu(::Window * pParent,ViewShellBase & rViewShellBase,const cssu::Reference<css::ui::XSidebar> & rxSidebar)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 
implConstruct(DrawDocShell & rDocumentShell)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 
~LayoutMenu(void)212 LayoutMenu::~LayoutMenu (void)
213 {
214     OSL_TRACE("destroying LayoutMenu at %x", this);
215     Dispose();
216 }
217 
218 
219 
220 
Dispose(void)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 
GetSelectedAutoLayout(void)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 */
GetPreferredSize(void)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 
GetPreferredWidth(sal_Int32 nHeight)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 
GetHeightForWidth(const sal_Int32 nWidth)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 
GetMinimumWidth(void)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 
Paint(const Rectangle & rRect)342 void LayoutMenu::Paint (const Rectangle& rRect)
343 {
344     if (mbSelectionUpdatePending)
345     {
346         mbSelectionUpdatePending = false;
347         UpdateSelection();
348     }
349     ValueSet::Paint (rRect);
350 }
351 
352 
353 
354 
Resize(void)355 void LayoutMenu::Resize (void)
356 {
357     Size aWindowSize = GetOutputSizePixel();
358     if (IsVisible() && aWindowSize.Width() > 0)
359     {
360         // Calculate the number of rows and columns.
361         if (GetItemCount() > 0)
362         {
363             Image aImage = GetItemImage(GetItemId(0));
364             Size aItemSize = CalcItemSizePixel (
365                 aImage.GetSizePixel());
366             aItemSize.Width() += 8;
367             aItemSize.Height() += 8;
368             int nColumnCount = aWindowSize.Width() / aItemSize.Width();
369             if (nColumnCount < 1)
370                 nColumnCount = 1;
371             else if (nColumnCount > 4)
372                 nColumnCount = 4;
373 
374             int nRowCount = CalculateRowCount (aItemSize, nColumnCount);
375 
376             SetColCount ((sal_uInt16)nColumnCount);
377             SetLineCount ((sal_uInt16)nRowCount);
378         }
379     }
380 
381     ValueSet::Resize ();
382 }
383 
384 
385 
386 
MouseButtonDown(const MouseEvent & rEvent)387 void LayoutMenu::MouseButtonDown (const MouseEvent& rEvent)
388 {
389     // As a preparation for the context menu the item under the mouse is
390     // selected.
391     if (rEvent.IsRight())
392     {
393         ReleaseMouse();
394         sal_uInt16 nIndex = GetItemId (rEvent.GetPosPixel());
395         if (nIndex > 0)
396             SelectItem(nIndex);
397     }
398 
399     ValueSet::MouseButtonDown (rEvent);
400 }
401 
402 
403 
404 
InsertPageWithLayout(AutoLayout aLayout)405 void LayoutMenu::InsertPageWithLayout (AutoLayout aLayout)
406 {
407     ViewShell* pViewShell = mrBase.GetMainViewShell().get();
408     if (pViewShell == NULL)
409         return;
410 
411     SfxViewFrame* pViewFrame = mrBase.GetViewFrame();
412     if (pViewFrame == NULL)
413         return;
414 
415     SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher();
416     if (pDispatcher == NULL)
417         return;
418 
419     // Call SID_INSERTPAGE with the right arguments.  This is because
420     // the popup menu can not call this slot with arguments directly.
421     SfxRequest aRequest (CreateRequest(SID_INSERTPAGE, aLayout));
422     if (aRequest.GetArgs() != NULL)
423     {
424         pDispatcher->Execute(
425             SID_INSERTPAGE,
426             SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
427             *aRequest.GetArgs());
428     }
429     UpdateSelection();
430 }
431 
432 
433 
434 
InvalidateContent(void)435 void LayoutMenu::InvalidateContent (void)
436 {
437     // Throw away the current set and fill the menu anew according to the
438     // current settings (this includes the support for vertical writing.)
439     Fill();
440 
441     if (mxSidebar.is())
442         mxSidebar->requestLayout();
443 }
444 
445 
446 
447 
CalculateRowCount(const Size &,int nColumnCount)448 int LayoutMenu::CalculateRowCount (const Size&, int nColumnCount)
449 {
450     int nRowCount = 0;
451 
452     if (GetItemCount() > 0 && nColumnCount > 0)
453     {
454         nRowCount = (GetItemCount() + nColumnCount - 1) / nColumnCount;
455         //        nRowCount = GetOutputSizePixel().Height() / rItemSize.Height();
456         if (nRowCount < 1)
457             nRowCount = 1;
458     }
459 
460     return nRowCount;
461 }
462 
463 
464 
465 
IMPL_LINK(LayoutMenu,ClickHandler,ValueSet *,EMPTYARG)466 IMPL_LINK(LayoutMenu, ClickHandler, ValueSet*, EMPTYARG)
467 {
468     AssignLayoutToSelectedSlides (GetSelectedAutoLayout());
469     return 0;
470 }
471 
472 
473 
474 
475 /** The specified layout is assigned to the current page of the view shell
476     in the center pane.
477 */
AssignLayoutToSelectedSlides(AutoLayout aLayout)478 void LayoutMenu::AssignLayoutToSelectedSlides (AutoLayout aLayout)
479 {
480     using namespace ::sd::slidesorter;
481     using namespace ::sd::slidesorter::controller;
482 
483     do
484     {
485         // The view shell in the center pane has to be present.
486         ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
487         if (pMainViewShell == NULL)
488             break;
489 
490         // Determine if the current view is in an invalid master page mode.
491         // The handout view is always in master page mode and therefore not
492         // invalid.
493         bool bMasterPageMode (false);
494         switch (pMainViewShell->GetShellType())
495         {
496             case ViewShell::ST_NOTES:
497             case ViewShell::ST_IMPRESS:
498             {
499                 DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(pMainViewShell);
500                 if (pDrawViewShell != NULL)
501                     if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
502                         bMasterPageMode = true;
503             }
504 			default:
505 				break;
506         }
507         if (bMasterPageMode)
508             break;
509 
510         // Get a list of all selected slides and call the SID_MODIFYPAGE
511         // slot for all of them.
512 		::sd::slidesorter::SharedPageSelection pPageSelection;
513 
514         // Get a list of selected pages.
515         // First we try to obtain this list from a slide sorter.  This is
516         // possible only some of the view shells in the center pane.  When
517         // no valid slide sorter is available then ask the main view shell
518         // for its current page.
519         SlideSorterViewShell* pSlideSorter = NULL;
520         switch (pMainViewShell->GetShellType())
521         {
522             case ViewShell::ST_IMPRESS:
523             case ViewShell::ST_NOTES:
524             case ViewShell::ST_SLIDE_SORTER:
525                 pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase);
526                 break;
527 			default:
528 				break;
529         }
530 		if (pSlideSorter != NULL)
531 		{
532 			// There is a slide sorter visible so get the list of selected pages from it.
533             pPageSelection = pSlideSorter->GetPageSelection();
534 		}
535 
536 		if( (pSlideSorter == NULL) || (pPageSelection.get() == 0) || pPageSelection->empty() )
537 		{
538 			// No valid slide sorter available.  Ask the main view shell for
539 			// its current page.
540             pPageSelection.reset(new ::sd::slidesorter::SlideSorterViewShell::PageSelection());
541             pPageSelection->push_back(pMainViewShell->GetActualPage());
542 		}
543 
544 
545 		if (pPageSelection->empty())
546 			break;
547 
548 		::std::vector<SdPage*>::iterator iPage;
549 		for (iPage=pPageSelection->begin(); iPage!=pPageSelection->end(); ++iPage)
550 			{
551 				if ((*iPage) == NULL)
552 					continue;
553 
554 				// Call the SID_ASSIGN_LAYOUT slot with all the necessary parameters.
555 				SfxRequest aRequest (mrBase.GetViewFrame(), SID_ASSIGN_LAYOUT);
556 				aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATPAGE, ((*iPage)->GetPageNum()-1)/2));
557 				aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
558 				pMainViewShell->ExecuteSlot (aRequest, sal_Bool(sal_False));
559 			}
560     }
561     while(false);
562 }
563 
564 
565 
566 
CreateRequest(sal_uInt16 nSlotId,AutoLayout aLayout)567 SfxRequest LayoutMenu::CreateRequest (
568     sal_uInt16 nSlotId,
569     AutoLayout aLayout)
570 {
571     SfxRequest aRequest (mrBase.GetViewFrame(), nSlotId);
572 
573     do
574     {
575         SdrLayerAdmin& rLayerAdmin (mrBase.GetDocument()->GetLayerAdmin());
576         sal_uInt8 aBackground (rLayerAdmin.GetLayerID(
577             String(SdResId(STR_LAYER_BCKGRND)), sal_False));
578         sal_uInt8 aBackgroundObject (rLayerAdmin.GetLayerID(
579             String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False));
580         ViewShell* pViewShell = mrBase.GetMainViewShell().get();
581         if (pViewShell == NULL)
582             break;
583         SdPage* pPage = pViewShell->GetActualPage();
584         if (pPage == NULL)
585             break;
586 
587         SetOfByte aVisibleLayers (pPage->TRG_GetMasterPageVisibleLayers());
588 
589         aRequest.AppendItem(
590             SfxStringItem (ID_VAL_PAGENAME, String()));//pPage->GetName()));
591         aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
592         aRequest.AppendItem(
593             SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground)));
594         aRequest.AppendItem(
595             SfxBoolItem(
596                 ID_VAL_ISPAGEOBJ,
597                 aVisibleLayers.IsSet(aBackgroundObject)));
598     }
599     while (false);
600 
601     return aRequest;
602 }
603 
604 
605 
606 
Fill(void)607 void LayoutMenu::Fill (void)
608 {
609 	const bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
610 	SvtLanguageOptions aLanguageOptions;
611     sal_Bool bVertical = aLanguageOptions.IsVerticalTextEnabled();
612     SdDrawDocument* pDocument = mrBase.GetDocument();
613     sal_Bool bRightToLeft = (pDocument!=NULL
614         && pDocument->GetDefaultWritingMode() == WritingMode_RL_TB);
615 
616     // Get URL of the view in the center pane.
617     ::rtl::OUString sCenterPaneViewName;
618     try
619     {
620         Reference<XControllerManager> xControllerManager (
621             Reference<XWeak>(&mrBase.GetDrawController()), UNO_QUERY_THROW);
622         Reference<XResourceId> xPaneId (ResourceId::create(
623             ::comphelper::getProcessComponentContext(),
624             FrameworkHelper::msCenterPaneURL));
625         Reference<XView> xView (FrameworkHelper::Instance(mrBase)->GetView(xPaneId));
626         if (xView.is())
627             sCenterPaneViewName = xView->getResourceId()->getResourceURL();
628     }
629     catch (RuntimeException&)
630     {}
631 
632 	snewfoil_value_info* pInfo = NULL;
633     if (sCenterPaneViewName.equals(framework::FrameworkHelper::msNotesViewURL))
634     {
635         pInfo = notes;
636     }
637     else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msHandoutViewURL))
638     {
639         pInfo = handout;
640     }
641     else if (sCenterPaneViewName.equals(framework::FrameworkHelper::msImpressViewURL)
642         || sCenterPaneViewName.equals(framework::FrameworkHelper::msSlideSorterURL))
643     {
644         pInfo = standard;
645     }
646     else
647     {
648         pInfo = NULL;
649 	}
650 
651     Clear();
652     int n = 0;
653 	for (sal_uInt16 i=1; pInfo!=NULL&&pInfo->mnBmpResId!=0; i++,pInfo++)
654 	{
655         if ((WritingMode_TB_RL != pInfo->meWritingMode) || bVertical)
656         {
657             BitmapEx aBmp (SdResId (bHighContrast
658                              ? pInfo->mnHCBmpResId
659                              : pInfo->mnBmpResId));
660 
661             if (bRightToLeft && (WritingMode_TB_RL != pInfo->meWritingMode))
662                 aBmp.Mirror (BMP_MIRROR_HORZ);
663 
664             InsertItem (i, aBmp, String (SdResId (pInfo->mnStrResId)));
665             SetItemData (i, new AutoLayout(pInfo->maAutoLayout));
666             n++;
667         }
668 	}
669 
670     mbSelectionUpdatePending = true;
671 }
672 
673 
674 
675 
Clear(void)676 void LayoutMenu::Clear (void)
677 {
678     for (sal_uInt16 nId=1; nId<=GetItemCount(); nId++)
679         delete static_cast<AutoLayout*>(GetItemData(nId));
680     ValueSet::Clear();
681 }
682 
683 
684 
StartDrag(sal_Int8,const Point &)685 void LayoutMenu::StartDrag (sal_Int8 , const Point& )
686 {
687 }
688 
689 
690 
691 
AcceptDrop(const AcceptDropEvent &)692 sal_Int8 LayoutMenu::AcceptDrop (const AcceptDropEvent& )
693 {
694     return 0;
695 }
696 
697 
698 
699 
ExecuteDrop(const ExecuteDropEvent &)700 sal_Int8 LayoutMenu::ExecuteDrop (const ExecuteDropEvent& )
701 {
702     return 0;
703 }
704 
705 
706 
707 
Command(const CommandEvent & rEvent)708 void LayoutMenu::Command (const CommandEvent& rEvent)
709 {
710     switch (rEvent.GetCommand())
711     {
712         case COMMAND_CONTEXTMENU:
713             if ( ! SD_MOD()->GetWaterCan())
714             {
715                 // Determine the position where to show the menu.
716                 Point aMenuPosition;
717                 if (rEvent.IsMouseEvent())
718                 {
719                     if (GetItemId(rEvent.GetMousePosPixel()) <= 0)
720                         return;
721                     aMenuPosition = rEvent.GetMousePosPixel();
722                 }
723                 else
724                 {
725                     if (GetSelectItemId() == (sal_uInt16)-1)
726                         return;
727                     Rectangle aBBox (GetItemRect(GetSelectItemId()));
728                     aMenuPosition = aBBox.Center();
729                 }
730 
731                 // Setup the menu.
732                 ::boost::shared_ptr<PopupMenu> pMenu (new PopupMenu(SdResId(RID_TASKPANE_LAYOUTMENU_POPUP)));
733                 FloatingWindow* pMenuWindow = dynamic_cast<FloatingWindow*>(pMenu->GetWindow());
734                 if (pMenuWindow != NULL)
735                     pMenuWindow->SetPopupModeFlags(
736                         pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE);
737                 pMenu->SetSelectHdl(LINK(this, LayoutMenu, OnMenuItemSelected));
738 
739                 // Disable the SID_INSERTPAGE_LAYOUT_MENU item when
740                 // the document is read-only.
741                 const SfxPoolItem* pItem = NULL;
742                 const SfxItemState aState (
743                     mrBase.GetViewFrame()->GetDispatcher()->QueryState(SID_INSERTPAGE, pItem));
744                 if (aState == SFX_ITEM_DISABLED)
745                     pMenu->EnableItem(SID_INSERTPAGE_LAYOUT_MENU, sal_False);
746 
747                 // Show the menu.
748                 pMenu->Execute(this, Rectangle(aMenuPosition,Size(1,1)), POPUPMENU_EXECUTE_DOWN);
749             }
750             break;
751 
752         default:
753             ValueSet::Command(rEvent);
754             break;
755     }
756 }
757 
758 
759 
760 
IMPL_LINK(LayoutMenu,StateChangeHandler,::rtl::OUString *,EMPTYARG)761 IMPL_LINK(LayoutMenu, StateChangeHandler, ::rtl::OUString*, EMPTYARG)
762 {
763     InvalidateContent();
764     return 0;
765 }
766 
767 
768 
769 
IMPL_LINK(LayoutMenu,OnMenuItemSelected,Menu *,pMenu)770 IMPL_LINK(LayoutMenu, OnMenuItemSelected, Menu*, pMenu)
771 {
772     if (pMenu == NULL)
773     {
774         OSL_ENSURE(pMenu!=NULL, "LayoutMenu::OnMenuItemSelected: illegal menu!");
775         return 0;
776     }
777 
778     pMenu->Deactivate();
779     const sal_Int32 nIndex (pMenu->GetCurItemId());
780 
781     if (nIndex == SID_TP_APPLY_TO_SELECTED_SLIDES)
782     {
783         AssignLayoutToSelectedSlides(GetSelectedAutoLayout());
784     }
785     else if (nIndex == SID_INSERTPAGE_LAYOUT_MENU)
786     {
787         // Add arguments to this slot and forward it to the main view
788         // shell.
789         InsertPageWithLayout(GetSelectedAutoLayout());
790     }
791 
792     return 0;
793 }
794 
795 
796 
797 
UpdateSelection(void)798 void LayoutMenu::UpdateSelection (void)
799 {
800     bool bItemSelected = false;
801 
802     do
803     {
804         // Get current page of main view.
805         ViewShell* pViewShell = mrBase.GetMainViewShell().get();
806         if (pViewShell == NULL)
807             break;
808 
809         SdPage* pCurrentPage = pViewShell->getCurrentPage();
810         if (pCurrentPage == NULL)
811             break;
812 
813         // Get layout of current page.
814         AutoLayout aLayout (pCurrentPage->GetAutoLayout());
815         if (aLayout<AUTOLAYOUT__START || aLayout>AUTOLAYOUT__END)
816             break;
817 
818         // Find the entry of the menu for to the layout.
819         SetNoSelection();
820         sal_uInt16 nItemCount (GetItemCount());
821         for (sal_uInt16 nId=1; nId<=nItemCount; nId++)
822         {
823             if (*static_cast<AutoLayout*>(GetItemData(nId)) == aLayout)
824             {
825                 SelectItem(nId);
826                 bItemSelected = true;
827                 break;
828             }
829         }
830     }
831     while (false);
832 
833     if ( ! bItemSelected)
834         SetNoSelection();
835 }
836 
837 
838 
839 
IMPL_LINK(LayoutMenu,EventMultiplexerListener,::sd::tools::EventMultiplexerEvent *,pEvent)840 IMPL_LINK(LayoutMenu, EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*, pEvent)
841 {
842     switch (pEvent->meEventId)
843     {
844         case ::sd::tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
845         case ::sd::tools::EventMultiplexerEvent::EID_SLIDE_SORTER_SELECTION:
846             if ( ! mbSelectionUpdatePending)
847                 UpdateSelection();
848             break;
849 
850         case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
851             mbIsMainViewChangePending = true;
852             break;
853 
854         case ::sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
855             HideFocus();
856             break;
857 
858         case ::sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
859             if (mbIsMainViewChangePending)
860             {
861                 mbIsMainViewChangePending = false;
862                 InvalidateContent();
863             }
864             break;
865 
866         default:
867             /* Ignored */
868             break;
869     }
870 
871     return 0;
872 }
873 
874 
875 
876 
IMPL_LINK(LayoutMenu,WindowEventHandler,VclWindowEvent *,pEvent)877 IMPL_LINK(LayoutMenu, WindowEventHandler, VclWindowEvent*, pEvent)
878 {
879     if (pEvent != NULL)
880     {
881         switch (pEvent->GetId())
882         {
883             case VCLEVENT_WINDOW_SHOW:
884             case VCLEVENT_WINDOW_RESIZE:
885                 SetSizePixel(GetParent()->GetSizePixel());
886                 return sal_True;
887 
888             default:
889                 return sal_False;
890         }
891 
892         const SfxSimpleHint* pSimpleHint = PTR_CAST(SfxSimpleHint, pEvent);
893         if (pSimpleHint != NULL
894             && pSimpleHint->GetId() == SFX_HINT_DYING)
895         {
896             return sal_True;
897         }
898     }
899 
900     return sal_False;
901 }
902 
903 
904 
905 
DataChanged(const DataChangedEvent & rEvent)906 void LayoutMenu::DataChanged (const DataChangedEvent& rEvent)
907 {
908     Fill();
909     ValueSet::DataChanged(rEvent);
910     SetBackground(sfx2::sidebar::Theme::GetWallpaper(sfx2::sidebar::Theme::Paint_PanelBackground));
911     SetColor(sfx2::sidebar::Theme::GetColor(sfx2::sidebar::Theme::Paint_PanelBackground));
912 }
913 
914 
915 
916 
917 
918 } } // end of namespace ::sd::sidebar
919