xref: /core/sfx2/source/dialog/backingwindow.cxx (revision f9779894)
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