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