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