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