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