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