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 #include "backingwindow.hxx" 21 #include <vcl/accel.hxx> 22 #include <vcl/event.hxx> 23 #include <vcl/help.hxx> 24 #include <vcl/ptrstyle.hxx> 25 #include <vcl/settings.hxx> 26 #include <vcl/svapp.hxx> 27 #include <vcl/syswin.hxx> 28 #include <vcl/virdev.hxx> 29 30 #include <unotools/historyoptions.hxx> 31 #include <unotools/moduleoptions.hxx> 32 #include <svtools/openfiledroptargetlistener.hxx> 33 #include <svtools/colorcfg.hxx> 34 #include <svtools/langhelp.hxx> 35 #include <templateviewitem.hxx> 36 37 #include <comphelper/processfactory.hxx> 38 #include <comphelper/propertysequence.hxx> 39 #include <sfx2/app.hxx> 40 #include <officecfg/Office/Common.hxx> 41 42 #include <tools/diagnose_ex.h> 43 44 #include <com/sun/star/configuration/theDefaultProvider.hpp> 45 #include <com/sun/star/container/XNameAccess.hpp> 46 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> 47 #include <com/sun/star/document/MacroExecMode.hpp> 48 #include <com/sun/star/document/UpdateDocMode.hpp> 49 #include <com/sun/star/frame/Desktop.hpp> 50 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 51 #include <com/sun/star/system/SystemShellExecute.hpp> 52 #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 53 #include <com/sun/star/util/URLTransformer.hpp> 54 #include <com/sun/star/task/InteractionHandler.hpp> 55 56 using namespace ::com::sun::star; 57 using namespace ::com::sun::star::beans; 58 using namespace ::com::sun::star::frame; 59 using namespace ::com::sun::star::uno; 60 using namespace ::com::sun::star::document; 61 62 constexpr OUStringLiteral SERVICENAME_CFGREADACCESS = u"com.sun.star.configuration.ConfigurationAccess"; 63 64 class BrandImage final : public weld::CustomWidgetController 65 { 66 private: 67 BitmapEx maBrandImage; 68 bool mbIsDark = false; 69 70 public: 71 virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override 72 { 73 weld::CustomWidgetController::SetDrawingArea(pDrawingArea); 74 SetPointer(PointerStyle::RefHand); 75 } 76 77 virtual void Resize() override 78 { 79 auto nWidth = GetOutputSizePixel().Width(); 80 if (maBrandImage.GetSizePixel().Width() != nWidth) 81 LoadImageForWidth(nWidth); 82 weld::CustomWidgetController::Resize(); 83 } 84 85 void LoadImageForWidth(int nWidth) 86 { 87 mbIsDark = Application::GetSettings().GetStyleSettings().GetDialogColor().IsDark(); 88 SfxApplication::loadBrandSvg(mbIsDark ? "shell/logo-sc_inverted" : "shell/logo-sc", 89 maBrandImage, nWidth); 90 } 91 92 void ConfigureForWidth(int nWidth) 93 { 94 if (maBrandImage.GetSizePixel().Width() == nWidth) 95 return; 96 LoadImageForWidth(nWidth); 97 const Size aBmpSize(maBrandImage.GetSizePixel()); 98 set_size_request(aBmpSize.Width(), aBmpSize.Height()); 99 } 100 101 virtual void StyleUpdated() override 102 { 103 const bool bIsDark = Application::GetSettings().GetStyleSettings().GetDialogColor().IsDark(); 104 if (bIsDark != mbIsDark) 105 LoadImageForWidth(GetOutputSizePixel().Width()); 106 weld::CustomWidgetController::StyleUpdated(); 107 } 108 109 virtual bool MouseButtonUp(const MouseEvent& rMEvt) override 110 { 111 if (rMEvt.IsLeft()) 112 { 113 OUString sURL = officecfg::Office::Common::Menus::VolunteerURL::get(); 114 localizeWebserviceURI(sURL); 115 116 Reference<css::system::XSystemShellExecute> const xSystemShellExecute( 117 css::system::SystemShellExecute::create( 118 ::comphelper::getProcessComponentContext())); 119 xSystemShellExecute->execute(sURL, OUString(), 120 css::system::SystemShellExecuteFlags::URIS_ONLY); 121 } 122 return true; 123 } 124 125 virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override 126 { 127 rRenderContext.DrawBitmapEx(Point(0, 0), maBrandImage); 128 } 129 }; 130 131 // increase size of the text in the buttons on the left fMultiplier-times 132 float const g_fMultiplier = 1.4f; 133 134 BackingWindow::BackingWindow(vcl::Window* i_pParent) 135 : InterimItemWindow(i_pParent, "sfx/ui/startcenter.ui", "StartCenter", false) 136 , mxOpenButton(m_xBuilder->weld_button("open_all")) 137 , mxRecentButton(m_xBuilder->weld_menu_toggle_button("open_recent")) 138 , mxRemoteButton(m_xBuilder->weld_button("open_remote")) 139 , mxTemplateButton(m_xBuilder->weld_menu_toggle_button("templates_all")) 140 , mxCreateLabel(m_xBuilder->weld_label("create_label")) 141 , mxAltHelpLabel(m_xBuilder->weld_label("althelplabel")) 142 , mxWriterAllButton(m_xBuilder->weld_button("writer_all")) 143 , mxCalcAllButton(m_xBuilder->weld_button("calc_all")) 144 , mxImpressAllButton(m_xBuilder->weld_button("impress_all")) 145 , mxDrawAllButton(m_xBuilder->weld_button("draw_all")) 146 , mxDBAllButton(m_xBuilder->weld_button("database_all")) 147 , mxMathAllButton(m_xBuilder->weld_button("math_all")) 148 , mxBrandImage(new BrandImage) 149 , mxBrandImageWeld(new weld::CustomWeld(*m_xBuilder, "daBrand", *mxBrandImage)) 150 , mxHelpButton(m_xBuilder->weld_button("help")) 151 , mxExtensionsButton(m_xBuilder->weld_button("extensions")) 152 , mxAllButtonsBox(m_xBuilder->weld_container("all_buttons_box")) 153 , mxButtonsBox(m_xBuilder->weld_container("buttons_box")) 154 , mxSmallButtonsBox(m_xBuilder->weld_container("small_buttons_box")) 155 , mxAllRecentThumbnails(new sfx2::RecentDocsView(m_xBuilder->weld_scrolled_window("scrollrecent", true), 156 m_xBuilder->weld_menu("recentmenu"))) 157 , mxAllRecentThumbnailsWin(new weld::CustomWeld(*m_xBuilder, "all_recent", *mxAllRecentThumbnails)) 158 , mxLocalView(new TemplateDefaultView(m_xBuilder->weld_scrolled_window("scrolllocal", true), 159 m_xBuilder->weld_menu("localmenu"))) 160 , mxLocalViewWin(new weld::CustomWeld(*m_xBuilder, "local_view", *mxLocalView)) 161 , mbLocalViewInitialized(false) 162 , mbInitControls(false) 163 { 164 // init background 165 SetPaintTransparent(false); 166 SetBackground(svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor); 167 168 //set an alternative help label that doesn't hotkey the H of the Help menu 169 mxHelpButton->set_label(mxAltHelpLabel->get_label()); 170 mxHelpButton->connect_clicked(LINK(this, BackingWindow, ClickHelpHdl)); 171 172 mxDropTarget = mxAllRecentThumbnails->GetDropTarget(); 173 174 try 175 { 176 mxContext.set( ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW ); 177 } 178 catch (const Exception&) 179 { 180 TOOLS_WARN_EXCEPTION( "fwk", "BackingWindow" ); 181 } 182 183 SetStyle( GetStyle() | WB_DIALOGCONTROL ); 184 185 // get dispatch provider 186 Reference<XDesktop2> xDesktop = Desktop::create( comphelper::getProcessComponentContext() ); 187 mxDesktopDispatchProvider = xDesktop; 188 189 } 190 191 IMPL_LINK(BackingWindow, ClickHelpHdl, weld::Button&, rButton, void) 192 { 193 if (Help* pHelp = Application::GetHelp()) 194 pHelp->Start(OUString::fromUtf8(m_xContainer->get_help_id()), &rButton); 195 } 196 197 BackingWindow::~BackingWindow() 198 { 199 disposeOnce(); 200 } 201 202 void BackingWindow::dispose() 203 { 204 // deregister drag&drop helper 205 if (mxDropTargetListener.is()) 206 { 207 if (mxDropTarget.is()) 208 { 209 mxDropTarget->removeDropTargetListener(mxDropTargetListener); 210 mxDropTarget->setActive(false); 211 } 212 mxDropTargetListener.clear(); 213 } 214 mxDropTarget.clear(); 215 mxOpenButton.reset(); 216 mxRemoteButton.reset(); 217 mxRecentButton.reset(); 218 mxTemplateButton.reset(); 219 mxCreateLabel.reset(); 220 mxAltHelpLabel.reset(); 221 mxWriterAllButton.reset(); 222 mxCalcAllButton.reset(); 223 mxImpressAllButton.reset(); 224 mxDrawAllButton.reset(); 225 mxDBAllButton.reset(); 226 mxMathAllButton.reset(); 227 mxBrandImageWeld.reset(); 228 mxBrandImage.reset(); 229 mxHelpButton.reset(); 230 mxExtensionsButton.reset(); 231 mxAllButtonsBox.reset(); 232 mxButtonsBox.reset(); 233 mxSmallButtonsBox.reset(); 234 mxAllRecentThumbnailsWin.reset(); 235 mxAllRecentThumbnails.reset(); 236 mxLocalViewWin.reset(); 237 mxLocalView.reset(); 238 InterimItemWindow::dispose(); 239 } 240 241 void BackingWindow::initControls() 242 { 243 if( mbInitControls ) 244 return; 245 246 mbInitControls = true; 247 248 // collect the URLs of the entries in the File/New menu 249 SvtModuleOptions aModuleOptions; 250 251 if (aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER)) 252 mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_WRITER; 253 254 if (aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC)) 255 mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_CALC; 256 257 if (aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS)) 258 mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_IMPRESS; 259 260 if (aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW)) 261 mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_DRAW; 262 263 if (aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE)) 264 mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_DATABASE; 265 266 if (aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::MATH)) 267 mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_MATH; 268 269 mxAllRecentThumbnails->mnFileTypes |= sfx2::ApplicationType::TYPE_OTHER; 270 mxAllRecentThumbnails->Reload(); 271 mxAllRecentThumbnails->ShowTooltips( true ); 272 mxRecentButton->set_active(true); 273 mxRecentButton->grab_focus(); 274 275 //initialize Template view 276 mxLocalView->Hide(); 277 278 //set handlers 279 mxLocalView->setCreateContextMenuHdl(LINK(this, BackingWindow, CreateContextMenuHdl)); 280 mxLocalView->setOpenTemplateHdl(LINK(this, BackingWindow, OpenTemplateHdl)); 281 mxLocalView->setEditTemplateHdl(LINK(this, BackingWindow, EditTemplateHdl)); 282 mxLocalView->ShowTooltips( true ); 283 284 checkInstalledModules(); 285 286 mxExtensionsButton->connect_clicked(LINK(this, BackingWindow, ExtLinkClickHdl)); 287 288 mxOpenButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 289 mxRemoteButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 290 mxRecentButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 291 mxTemplateButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 292 mxWriterAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 293 mxDrawAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 294 mxCalcAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 295 mxDBAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 296 mxImpressAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 297 mxMathAllButton->connect_clicked(LINK(this, BackingWindow, ClickHdl)); 298 299 mxRecentButton->connect_selected(LINK(this, BackingWindow, MenuSelectHdl)); 300 mxTemplateButton->connect_selected(LINK(this, BackingWindow, MenuSelectHdl)); 301 302 ApplyStyleSettings(); 303 } 304 305 void BackingWindow::DataChanged(const DataChangedEvent& rDCEvt) 306 { 307 if ((rDCEvt.GetType() != DataChangedEventType::SETTINGS) 308 || !(rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) 309 { 310 InterimItemWindow::DataChanged(rDCEvt); 311 return; 312 } 313 314 ApplyStyleSettings(); 315 Invalidate(); 316 } 317 318 template <typename WidgetClass> 319 void BackingWindow::setLargerFont(WidgetClass& pWidget, const vcl::Font& rFont) 320 { 321 vcl::Font aFont(rFont); 322 aFont.SetFontSize(Size(0, aFont.GetFontSize().Height() * g_fMultiplier)); 323 pWidget->set_font(aFont); 324 } 325 326 void BackingWindow::ApplyStyleSettings() 327 { 328 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 329 const Color aButtonsBackground(rStyleSettings.GetWindowColor()); 330 const vcl::Font& aButtonFont(rStyleSettings.GetPushButtonFont()); 331 const vcl::Font& aLabelFont(rStyleSettings.GetLabelFont()); 332 333 // setup larger fonts 334 setLargerFont(mxOpenButton, aButtonFont); 335 setLargerFont(mxOpenButton, aButtonFont); 336 setLargerFont(mxRemoteButton, aButtonFont); 337 setLargerFont(mxRecentButton, aButtonFont); 338 setLargerFont(mxTemplateButton, aButtonFont); 339 setLargerFont(mxWriterAllButton, aButtonFont); 340 setLargerFont(mxDrawAllButton, aButtonFont); 341 setLargerFont(mxCalcAllButton, aButtonFont); 342 setLargerFont(mxDBAllButton, aButtonFont); 343 setLargerFont(mxImpressAllButton, aButtonFont); 344 setLargerFont(mxMathAllButton, aButtonFont); 345 setLargerFont(mxCreateLabel, aLabelFont); 346 347 mxAllButtonsBox->set_background(aButtonsBackground); 348 mxSmallButtonsBox->set_background(aButtonsBackground); 349 350 // compute the menubar height 351 sal_Int32 nMenuHeight = 0; 352 if (SystemWindow* pSystemWindow = GetSystemWindow()) 353 nMenuHeight = pSystemWindow->GetMenuBarHeight(); 354 355 // fdo#34392: we do the layout dynamically, the layout depends on the font, 356 // so we should handle data changed events (font changing) of the last child 357 // control, at this point all the controls have updated settings (i.e. font). 358 Size aPrefSize(mxAllButtonsBox->get_preferred_size()); 359 set_width_request(aPrefSize.Width()); 360 361 // Now set a brand image wide enough to fill this width 362 weld::DrawingArea* pDrawingArea = mxBrandImage->GetDrawingArea(); 363 mxBrandImage->ConfigureForWidth(aPrefSize.Width() - 364 (pDrawingArea->get_margin_start() + pDrawingArea->get_margin_end())); 365 // Refetch because the brand image height to match this width is now set 366 aPrefSize = mxAllButtonsBox->get_preferred_size(); 367 368 set_height_request(nMenuHeight + aPrefSize.Height()); 369 } 370 371 void BackingWindow::initializeLocalView() 372 { 373 if (!mbLocalViewInitialized) 374 { 375 mbLocalViewInitialized = true; 376 mxLocalView->Populate(); 377 mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::NONE)); 378 mxLocalView->showAllTemplates(); 379 } 380 } 381 382 void BackingWindow::checkInstalledModules() 383 { 384 SvtModuleOptions aModuleOpt; 385 386 mxWriterAllButton->set_sensitive( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER )); 387 mxCalcAllButton->set_sensitive( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) ); 388 mxImpressAllButton->set_sensitive( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) ); 389 mxDrawAllButton->set_sensitive( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) ); 390 mxMathAllButton->set_sensitive(aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH )); 391 mxDBAllButton->set_sensitive(aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE )); 392 } 393 394 bool BackingWindow::PreNotify(NotifyEvent& rNEvt) 395 { 396 if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ) 397 { 398 const KeyEvent* pEvt = rNEvt.GetKeyEvent(); 399 const vcl::KeyCode& rKeyCode(pEvt->GetKeyCode()); 400 401 bool bThumbnailHasFocus = mxAllRecentThumbnails->HasFocus() || mxLocalView->HasFocus(); 402 403 // Subwindows of BackingWindow: Sidebar and Thumbnail view 404 if( rKeyCode.GetCode() == KEY_F6 ) 405 { 406 if( rKeyCode.IsShift() ) // Shift + F6 407 { 408 if (bThumbnailHasFocus) 409 { 410 mxOpenButton->grab_focus(); 411 return true; 412 } 413 } 414 else if ( rKeyCode.IsMod1() ) // Ctrl + F6 415 { 416 if(mxAllRecentThumbnails->IsVisible()) 417 { 418 mxAllRecentThumbnails->GrabFocus(); 419 return true; 420 } 421 else if(mxLocalView->IsVisible()) 422 { 423 mxLocalView->GrabFocus(); 424 return true; 425 } 426 } 427 else // F6 428 { 429 if (!bThumbnailHasFocus) 430 { 431 if(mxAllRecentThumbnails->IsVisible()) 432 { 433 mxAllRecentThumbnails->GrabFocus(); 434 return true; 435 } 436 else if(mxLocalView->IsVisible()) 437 { 438 mxLocalView->GrabFocus(); 439 return true; 440 } 441 } 442 } 443 } 444 445 // try the 'normal' accelerators (so that eg. Ctrl+Q works) 446 if (!mpAccExec) 447 { 448 mpAccExec = svt::AcceleratorExecute::createAcceleratorHelper(); 449 mpAccExec->init( comphelper::getProcessComponentContext(), mxFrame); 450 } 451 452 const OUString aCommand = mpAccExec->findCommand(svt::AcceleratorExecute::st_VCLKey2AWTKey(rKeyCode)); 453 if ((aCommand != "vnd.sun.star.findbar:FocusToFindbar") && pEvt && mpAccExec->execute(rKeyCode)) 454 return true; 455 } 456 else if (rNEvt.GetType() == MouseNotifyEvent::COMMAND) 457 { 458 Accelerator::ToggleMnemonicsOnHierarchy(*rNEvt.GetCommandEvent(), this); 459 } 460 return InterimItemWindow::PreNotify( rNEvt ); 461 } 462 463 void BackingWindow::GetFocus() 464 { 465 GetFocusFlags nFlags = GetParent()->GetGetFocusFlags(); 466 if( nFlags & GetFocusFlags::F6 ) 467 { 468 if( nFlags & GetFocusFlags::Forward ) // F6 469 { 470 mxOpenButton->grab_focus(); 471 return; 472 } 473 else // Shift + F6 or Ctrl + F6 474 { 475 if(mxAllRecentThumbnails->IsVisible()) 476 mxAllRecentThumbnails->GrabFocus(); 477 else if(mxLocalView->IsVisible()) 478 mxLocalView->GrabFocus(); 479 return; 480 } 481 } 482 InterimItemWindow::GetFocus(); 483 } 484 485 void BackingWindow::setOwningFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) 486 { 487 mxFrame = xFrame; 488 if( ! mbInitControls ) 489 initControls(); 490 491 // establish drag&drop mode 492 mxDropTargetListener.set(new OpenFileDropTargetListener(mxContext, mxFrame)); 493 494 if (mxDropTarget.is()) 495 { 496 mxDropTarget->addDropTargetListener(mxDropTargetListener); 497 mxDropTarget->setActive(true); 498 } 499 500 css::uno::Reference<XFramesSupplier> xFramesSupplier(mxDesktopDispatchProvider, UNO_QUERY); 501 if (xFramesSupplier) 502 xFramesSupplier->setActiveFrame(mxFrame); 503 } 504 505 IMPL_LINK(BackingWindow, ExtLinkClickHdl, weld::Button&, rButton, void) 506 { 507 OUString aNode; 508 509 if (&rButton == mxExtensionsButton.get()) 510 aNode = "AddFeatureURL"; 511 512 if (aNode.isEmpty()) 513 return; 514 515 try 516 { 517 uno::Sequence<uno::Any> args(comphelper::InitAnyPropertySequence( 518 { 519 {"nodepath", uno::Any(OUString("/org.openoffice.Office.Common/Help/StartCenter"))} 520 })); 521 522 Reference<lang::XMultiServiceFactory> xConfig = configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() ); 523 Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS, args), UNO_QUERY); 524 if (xNameAccess.is()) 525 { 526 OUString sURL; 527 Any value(xNameAccess->getByName(aNode)); 528 529 sURL = value.get<OUString>(); 530 localizeWebserviceURI(sURL); 531 532 Reference<css::system::XSystemShellExecute> const 533 xSystemShellExecute( 534 css::system::SystemShellExecute::create( 535 ::comphelper::getProcessComponentContext())); 536 xSystemShellExecute->execute(sURL, OUString(), 537 css::system::SystemShellExecuteFlags::URIS_ONLY); 538 } 539 } 540 catch (const Exception&) 541 { 542 } 543 } 544 545 IMPL_LINK( BackingWindow, ClickHdl, weld::Button&, rButton, void ) 546 { 547 // dispatch the appropriate URL and end the dialog 548 if( &rButton == mxWriterAllButton.get() ) 549 dispatchURL( "private:factory/swriter" ); 550 else if( &rButton == mxCalcAllButton.get() ) 551 dispatchURL( "private:factory/scalc" ); 552 else if( &rButton == mxImpressAllButton.get() ) 553 dispatchURL( "private:factory/simpress?slot=6686" ); 554 else if( &rButton == mxDrawAllButton.get() ) 555 dispatchURL( "private:factory/sdraw" ); 556 else if( &rButton == mxDBAllButton.get() ) 557 dispatchURL( "private:factory/sdatabase?Interactive" ); 558 else if( &rButton == mxMathAllButton.get() ) 559 dispatchURL( "private:factory/smath" ); 560 else if( &rButton == mxOpenButton.get() ) 561 { 562 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 563 564 Sequence< css::beans::PropertyValue > aArgs(1); 565 PropertyValue* pArg = aArgs.getArray(); 566 pArg[0].Name = "Referer"; 567 pArg[0].Value <<= OUString("private:user"); 568 569 dispatchURL( ".uno:Open", OUString(), xFrame, aArgs ); 570 } 571 else if( &rButton == mxRemoteButton.get() ) 572 { 573 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 574 575 Sequence< css::beans::PropertyValue > aArgs(0); 576 577 dispatchURL( ".uno:OpenRemote", OUString(), xFrame, aArgs ); 578 } 579 else if( &rButton == mxRecentButton.get() ) 580 { 581 mxLocalView->Hide(); 582 mxAllRecentThumbnails->Show(); 583 mxAllRecentThumbnails->GrabFocus(); 584 mxRecentButton->set_active(true); 585 mxTemplateButton->set_active(false); 586 } 587 else if( &rButton == mxTemplateButton.get() ) 588 { 589 mxAllRecentThumbnails->Hide(); 590 initializeLocalView(); 591 mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::NONE)); 592 mxLocalView->Show(); 593 mxLocalView->reload(); 594 mxLocalView->GrabFocus(); 595 mxRecentButton->set_active(false); 596 mxTemplateButton->set_active(true); 597 } 598 } 599 600 IMPL_LINK (BackingWindow, MenuSelectHdl, const OString&, rId, void) 601 { 602 if (rId == "clear_all") 603 { 604 SvtHistoryOptions().Clear(EHistoryType::PickList); 605 mxAllRecentThumbnails->Reload(); 606 return; 607 } 608 else if (!rId.isEmpty()) 609 { 610 initializeLocalView(); 611 612 if( rId == "filter_writer" ) 613 { 614 mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::WRITER)); 615 } 616 else if( rId == "filter_calc" ) 617 { 618 mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::CALC)); 619 } 620 else if( rId == "filter_impress" ) 621 { 622 mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::IMPRESS)); 623 } 624 else if( rId == "filter_draw" ) 625 { 626 mxLocalView->filterItems(ViewFilter_Application(FILTER_APPLICATION::DRAW)); 627 } 628 else if( rId == "manage" ) 629 { 630 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 631 632 Sequence< css::beans::PropertyValue > aArgs(1); 633 PropertyValue* pArg = aArgs.getArray(); 634 pArg[0].Name = "Referer"; 635 pArg[0].Value <<= OUString("private:user"); 636 637 dispatchURL( ".uno:NewDoc", OUString(), xFrame, aArgs ); 638 return; 639 } 640 641 mxAllRecentThumbnails->Hide(); 642 mxLocalView->Show(); 643 mxLocalView->reload(); 644 mxLocalView->GrabFocus(); 645 mxRecentButton->set_active(false); 646 mxTemplateButton->set_active(true); 647 } 648 } 649 650 IMPL_LINK(BackingWindow, CreateContextMenuHdl, ThumbnailViewItem*, pItem, void) 651 { 652 const TemplateViewItem *pViewItem = dynamic_cast<TemplateViewItem*>(pItem); 653 654 if (pViewItem) 655 mxLocalView->createContextMenu(); 656 } 657 658 IMPL_LINK(BackingWindow, OpenTemplateHdl, ThumbnailViewItem*, pItem, void) 659 { 660 uno::Sequence< PropertyValue > aArgs(4); 661 aArgs[0].Name = "AsTemplate"; 662 aArgs[0].Value <<= true; 663 aArgs[1].Name = "MacroExecutionMode"; 664 aArgs[1].Value <<= MacroExecMode::USE_CONFIG; 665 aArgs[2].Name = "UpdateDocMode"; 666 aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG; 667 aArgs[3].Name = "InteractionHandler"; 668 aArgs[3].Value <<= task::InteractionHandler::createWithParent( ::comphelper::getProcessComponentContext(), nullptr ); 669 670 TemplateViewItem *pTemplateItem = static_cast<TemplateViewItem*>(pItem); 671 672 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 673 674 try 675 { 676 dispatchURL( pTemplateItem->getPath(), "_default", xFrame, aArgs ); 677 } 678 catch( const uno::Exception& ) 679 { 680 } 681 } 682 683 IMPL_LINK(BackingWindow, EditTemplateHdl, ThumbnailViewItem*, pItem, void) 684 { 685 uno::Sequence< PropertyValue > aArgs(3); 686 aArgs[0].Name = "AsTemplate"; 687 aArgs[0].Value <<= false; 688 aArgs[1].Name = "MacroExecutionMode"; 689 aArgs[1].Value <<= MacroExecMode::USE_CONFIG; 690 aArgs[2].Name = "UpdateDocMode"; 691 aArgs[2].Value <<= UpdateDocMode::ACCORDING_TO_CONFIG; 692 693 TemplateViewItem *pViewItem = static_cast<TemplateViewItem*>(pItem); 694 695 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 696 697 try 698 { 699 dispatchURL( pViewItem->getPath(), "_default", xFrame, aArgs ); 700 } 701 catch( const uno::Exception& ) 702 { 703 } 704 } 705 706 namespace { 707 708 struct ImplDelayedDispatch 709 { 710 Reference< XDispatch > xDispatch; 711 css::util::URL aDispatchURL; 712 Sequence< PropertyValue > aArgs; 713 714 ImplDelayedDispatch( const Reference< XDispatch >& i_xDispatch, 715 const css::util::URL& i_rURL, 716 const Sequence< PropertyValue >& i_rArgs ) 717 : xDispatch( i_xDispatch ), 718 aDispatchURL( i_rURL ), 719 aArgs( i_rArgs ) 720 { 721 } 722 }; 723 724 } 725 726 static void implDispatchDelayed( void*, void* pArg ) 727 { 728 struct ImplDelayedDispatch* pDispatch = static_cast<ImplDelayedDispatch*>(pArg); 729 try 730 { 731 pDispatch->xDispatch->dispatch( pDispatch->aDispatchURL, pDispatch->aArgs ); 732 } 733 catch (const Exception&) 734 { 735 } 736 737 // clean up 738 delete pDispatch; 739 } 740 741 void BackingWindow::dispatchURL( const OUString& i_rURL, 742 const OUString& rTarget, 743 const Reference< XDispatchProvider >& i_xProv, 744 const Sequence< PropertyValue >& i_rArgs ) 745 { 746 // if no special dispatch provider is given, get the desktop 747 Reference< XDispatchProvider > xProvider( i_xProv.is() ? i_xProv : mxDesktopDispatchProvider ); 748 749 // check for dispatch provider 750 if( !xProvider.is()) 751 return; 752 753 // get a URL transformer to clean up the URL 754 css::util::URL aDispatchURL; 755 aDispatchURL.Complete = i_rURL; 756 757 Reference < css::util::XURLTransformer > xURLTransformer( 758 css::util::URLTransformer::create( comphelper::getProcessComponentContext() ) ); 759 try 760 { 761 // clean up the URL 762 xURLTransformer->parseStrict( aDispatchURL ); 763 // get a Dispatch for the URL and target 764 Reference< XDispatch > xDispatch( 765 xProvider->queryDispatch( aDispatchURL, rTarget, 0 ) 766 ); 767 // dispatch the URL 768 if ( xDispatch.is() ) 769 { 770 std::unique_ptr<ImplDelayedDispatch> pDisp(new ImplDelayedDispatch( xDispatch, aDispatchURL, i_rArgs )); 771 if( Application::PostUserEvent( Link<void*,void>( nullptr, implDispatchDelayed ), pDisp.get() ) ) 772 pDisp.release(); 773 } 774 } 775 catch (const css::uno::RuntimeException&) 776 { 777 throw; 778 } 779 catch (const css::uno::Exception&) 780 { 781 } 782 } 783 784 void BackingWindow::clearRecentFileList() 785 { 786 mxAllRecentThumbnails->Clear(); 787 } 788 /* vim:set shiftwidth=4 softtabstop=4 expandtab:*/ 789
