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 
23 
24 // autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 #include "backingwindow.hxx"
28 #include "classes/resource.hrc"
29 #include "framework.hrc"
30 #include "classes/fwkresid.hxx"
31 #include <services.h>
32 
33 #include "vcl/metric.hxx"
34 #include "vcl/mnemonic.hxx"
35 #include "vcl/menu.hxx"
36 #include "vcl/svapp.hxx"
37 
38 #include "tools/urlobj.hxx"
39 
40 #include "unotools/dynamicmenuoptions.hxx"
41 #include "unotools/historyoptions.hxx"
42 #include "svtools/imagemgr.hxx"
43 #include "svtools/svtools.hrc"
44 
45 #include "comphelper/processfactory.hxx"
46 #include "comphelper/sequenceashashmap.hxx"
47 #include "comphelper/configurationhelper.hxx"
48 
49 #include <toolkit/awt/vclxmenu.hxx>
50 
51 #include "cppuhelper/implbase1.hxx"
52 
53 #include "rtl/strbuf.hxx"
54 #include "rtl/ustrbuf.hxx"
55 #include "osl/file.h"
56 
57 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
58 #include "com/sun/star/container/XNameAccess.hpp"
59 #include "com/sun/star/system/SystemShellExecute.hpp"
60 #include "com/sun/star/system/SystemShellExecuteFlags.hpp"
61 #include "com/sun/star/task/XJobExecutor.hpp"
62 #include "com/sun/star/util/XStringWidth.hpp"
63 #include <com/sun/star/frame/PopupMenuControllerFactory.hpp>
64 
65 using namespace ::com::sun::star::beans;
66 using namespace ::com::sun::star::frame;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star;
69 using namespace framework;
70 
71 #define RECENT_FILE_LIST    ".uno:RecentFileList"
72 
73 #define WRITER_URL      "private:factory/swriter"
74 #define CALC_URL        "private:factory/scalc"
75 #define IMPRESS_WIZARD_URL     "private:factory/simpress?slot=6686"
76 #define DRAW_URL        "private:factory/sdraw"
77 #define BASE_URL        "private:factory/sdatabase?Interactive"
78 #define MATH_URL        "private:factory/smath"
79 #define TEMPLATE_URL    "slot:5500"
80 #define OPEN_URL        ".uno:Open"
81 
DecoToolBox(Window * pParent,WinBits nStyle)82 DecoToolBox::DecoToolBox( Window* pParent, WinBits nStyle ) :
83     ToolBox( pParent, nStyle )
84 {
85         SetBackground();
86         SetPaintTransparent( sal_True );
87 }
88 
DataChanged(const DataChangedEvent & rDCEvt)89 void DecoToolBox::DataChanged( const DataChangedEvent& rDCEvt )
90 {
91     Window::DataChanged( rDCEvt );
92 
93     if ( rDCEvt.GetFlags() & SETTINGS_STYLE )
94     {
95         calcMinSize();
96         SetBackground();
97         SetPaintTransparent( sal_True );
98     }
99 }
100 
calcMinSize()101 void DecoToolBox::calcMinSize()
102 {
103     ToolBox aTbx( GetParent() );
104     sal_uInt16 nItems = GetItemCount();
105     for( sal_uInt16 i = 0; i < nItems; i++ )
106     {
107         sal_uInt16 nId = GetItemId( i );
108         aTbx.InsertItem( nId, GetItemImage( nId ) );
109     }
110     aTbx.SetOutStyle( TOOLBOX_STYLE_FLAT );
111     maMinSize = aTbx.CalcWindowSizePixel();
112 }
113 
getMinSize()114 Size DecoToolBox::getMinSize()
115 {
116     return maMinSize;
117 }
118 
119 class RecentFilesStringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
120 {
121 	public:
RecentFilesStringLength()122 		RecentFilesStringLength() {}
~RecentFilesStringLength()123 		virtual ~RecentFilesStringLength() {}
124 
125 		// XStringWidth
queryStringWidth(const::rtl::OUString & aString)126 		sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
127 			throw (::com::sun::star::uno::RuntimeException)
128 		{
129 			return aString.getLength();
130 		}
131 };
132 
133 #define STC_BUTTON_STYLE  (WB_LEFT | WB_VCENTER | WB_FLATBUTTON | WB_BEVELBUTTON)
134 
BackingWindow(Window * i_pParent)135 BackingWindow::BackingWindow( Window* i_pParent ) :
136     Window( i_pParent, FwkResId( DLG_BACKING ) ),
137     maWelcome( this, WB_LEFT ),
138     maProduct( this, WB_LEFT ),
139     maWriterButton( this, STC_BUTTON_STYLE ),
140     maCalcButton( this, STC_BUTTON_STYLE ),
141     maImpressButton( this, STC_BUTTON_STYLE ),
142     maOpenButton( this, STC_BUTTON_STYLE ),
143     maDrawButton( this, STC_BUTTON_STYLE ),
144     maDBButton( this, STC_BUTTON_STYLE ),
145     maMathButton( this, STC_BUTTON_STYLE ),
146     maTemplateButton( this, STC_BUTTON_STYLE ),
147     maToolbox( this, WB_DIALOGCONTROL ),
148     maWelcomeString( FwkResId( STR_BACKING_WELCOME ) ),
149     maProductString( FwkResId( STR_BACKING_WELCOMEPRODUCT ) ),
150     maOpenString( FwkResId( STR_BACKING_FILE ) ),
151     maTemplateString( FwkResId( STR_BACKING_TEMPLATE ) ),
152     maButtonImageSize( 10, 10 ),
153     mbInitControls( false ),
154     mnLayoutStyle( 0 ),
155     mpAccExec( NULL ),
156     mnBtnPos( 120 ),
157     mnBtnTop( 150 )
158 {
159     mnColumnWidth[0] = mnColumnWidth[1] = 0;
160     mnTextColumnWidth[0] = mnTextColumnWidth[1] = 0;
161 
162     try
163     {
164         mxContext.set( ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW );
165 
166         Reference<lang::XMultiServiceFactory> xConfig(
167             mxContext->getServiceManager()->createInstanceWithContext(
168                 SERVICENAME_CFGPROVIDER, mxContext), UNO_QUERY);
169         if( xConfig.is() )
170         {
171             Sequence<Any> args(1);
172             PropertyValue val(
173                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("nodepath") ),
174                 0,
175                 Any(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Common/Help/StartCenter"))),
176                 PropertyState_DIRECT_VALUE);
177             args.getArray()[0] <<= val;
178             Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY);
179             if( xNameAccess.is() )
180             {
181                 //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
182                 Any value( xNameAccess->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartCenterLayoutStyle"))) );
183                 mnLayoutStyle = value.get<sal_Int32>();
184             }
185         }
186 
187         mxPopupMenuFactory.set(
188             frame::PopupMenuControllerFactory::create( mxContext ) );
189         // TODO If there is no PopupMenuController, the button should be a nomral one not a MenuButton
190         if ( mxPopupMenuFactory->hasController(
191             DECLARE_ASCII( RECENT_FILE_LIST ) , SERVICENAME_STARTMODULE ) )
192         {
193             mxPopupMenu.set( mxContext->getServiceManager()->createInstanceWithContext(
194                 DECLARE_ASCII( "com.sun.star.awt.PopupMenu" ), mxContext ), uno::UNO_QUERY_THROW );
195         }
196     }
197     catch (const Exception& e)
198     {
199         OSL_TRACE( "BackingWindow - caught an exception! %s",
200                    rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
201         (void) e;
202     }
203 
204     String aExtHelpText( FwkResId( STR_BACKING_EXTHELP ) );
205     String aRegHelpText( FwkResId( STR_BACKING_REGHELP ) );
206     String aInfoHelpText( FwkResId( STR_BACKING_INFOHELP ) );
207     String aTplRepHelpText( FwkResId( STR_BACKING_TPLREP ) );
208 
209     // clean up resource stack
210     FreeResource();
211 
212     maWelcome.SetPaintTransparent( sal_True );
213     maProduct.SetPaintTransparent( sal_True );
214     EnableChildTransparentMode();
215 
216     SetStyle( GetStyle() | WB_DIALOGCONTROL );
217 
218     // force tab cycling in toolbox
219     maToolbox.SetStyle( maToolbox.GetStyle() | WB_FORCETABCYCLE );
220 
221     // insert toolbox items
222     maToolbox.InsertItem( nItemId_TplRep, Image() );
223     maToolbox.SetItemText( nItemId_TplRep, aTplRepHelpText );
224     maToolbox.SetQuickHelpText( nItemId_TplRep, aTplRepHelpText );
225     maToolbox.SetItemCommand( nItemId_TplRep, String( RTL_CONSTASCII_USTRINGPARAM( ".HelpId:StartCenter:TemplateRepository" ) ) );
226     maToolbox.ShowItem( nItemId_TplRep );
227 
228     maToolbox.InsertItem( nItemId_Extensions, Image() );
229     maToolbox.SetQuickHelpText( nItemId_Extensions, aExtHelpText );
230     maToolbox.SetItemText( nItemId_Extensions, aExtHelpText );
231     maToolbox.SetItemCommand( nItemId_Extensions, String( RTL_CONSTASCII_USTRINGPARAM( ".HelpId:StartCenter:Extensions" ) ) );
232     maToolbox.ShowItem( nItemId_Extensions );
233 
234     maToolbox.InsertItem( nItemId_Info, Image() );
235     maToolbox.SetItemText( nItemId_Info, aInfoHelpText );
236     maToolbox.SetQuickHelpText( nItemId_Info, aInfoHelpText );
237     maToolbox.SetItemCommand( nItemId_Info, String( RTL_CONSTASCII_USTRINGPARAM( ".HelpId:StartCenter:Info" ) ) );
238     maToolbox.ShowItem( nItemId_Info );
239 
240     // get dispatch provider
241     mxDesktop = Reference<XDesktop>( comphelper::getProcessServiceFactory()->createInstance(SERVICENAME_DESKTOP ),UNO_QUERY );
242     if( mxDesktop.is() )
243         mxDesktopDispatchProvider = Reference< XDispatchProvider >( mxDesktop, UNO_QUERY );
244 
245     maWriterButton.SetHelpId( ".HelpId:StartCenter:WriterButton" );
246     maCalcButton.SetHelpId( ".HelpId:StartCenter:CalcButton" );
247     maImpressButton.SetHelpId( ".HelpId:StartCenter:ImpressButton" );
248     maDrawButton.SetHelpId( ".HelpId:StartCenter:DrawButton" );
249     maDBButton.SetHelpId( ".HelpId:StartCenter:DBButton" );
250     maMathButton.SetHelpId( ".HelpId:StartCenter:MathButton" );
251     maTemplateButton.SetHelpId( ".HelpId:StartCenter:TemplateButton" );
252     maOpenButton.SetHelpId( ".HelpId:StartCenter:OpenButton" );
253     maToolbox.SetHelpId( ".HelpId:StartCenter:Toolbox" );
254 
255     // init background
256     initBackground();
257 
258     // add some breathing space for the images
259     maButtonImageSize.Width() += 12;
260     maButtonImageSize.Height() += 12;
261 
262 }
263 
264 
~BackingWindow()265 BackingWindow::~BackingWindow()
266 {
267     delete mpAccExec;
268 
269     if( mxPopupMenuController.is() )
270     {
271         Reference< lang::XComponent > xComponent( mxPopupMenuController, UNO_QUERY );
272         if( xComponent.is() )
273         {
274             try
275             {
276                 xComponent->dispose();
277             }
278             catch (...)
279             {}
280         }
281         mxPopupMenuController.clear();
282     }
283     mxPopupMenuFactory.clear();
284     mxPopupMenu.clear();
285 }
286 
GetFocus()287 void BackingWindow::GetFocus()
288 {
289     if( IsVisible() )
290         maWriterButton.GrabFocus();
291     Window::GetFocus();
292 }
293 
294 class ImageContainerRes : public Resource
295 {
296     public:
ImageContainerRes(const ResId & i_rId)297     ImageContainerRes( const ResId& i_rId ) : Resource( i_rId ) {}
~ImageContainerRes()298     ~ImageContainerRes() { FreeResource(); }
299 };
300 
DataChanged(const DataChangedEvent & rDCEvt)301 void BackingWindow::DataChanged( const DataChangedEvent& rDCEvt )
302 {
303     Window::DataChanged( rDCEvt );
304 
305     if ( rDCEvt.GetFlags() & SETTINGS_STYLE )
306     {
307         initBackground();
308         Invalidate();
309     }
310 }
311 
prepareRecentFileMenu()312 void BackingWindow::prepareRecentFileMenu()
313 {
314     if( ! mxPopupMenu.is() )
315         return;
316 
317     if ( !mxPopupMenuController.is() )
318     {
319         uno::Sequence< uno::Any > aArgs( 2 );
320         beans::PropertyValue aProp;
321 
322         aProp.Name = DECLARE_ASCII( "Frame" );
323         aProp.Value <<= mxFrame;
324         aArgs[0] <<= aProp;
325 
326         aProp.Name = DECLARE_ASCII( "ModuleIdentifier" );
327         aProp.Value <<= SERVICENAME_STARTMODULE;
328         aArgs[1] <<= aProp;
329         try
330         {
331             mxPopupMenuController.set(
332                 mxPopupMenuFactory->createInstanceWithArgumentsAndContext(
333                     DECLARE_ASCII( RECENT_FILE_LIST ), aArgs, mxContext),
334                         uno::UNO_QUERY_THROW );
335             mxPopupMenuController->setPopupMenu( mxPopupMenu );
336         }
337         catch ( const Exception &e )
338         {
339             OSL_TRACE( "BackingWindow - caught an exception! %s",
340                        rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
341             (void) e;
342         }
343 
344         PopupMenu *pRecentMenu = NULL;
345         VCLXMenu* pTKMenu = VCLXMenu::GetImplementation( mxPopupMenu );
346         if ( pTKMenu )
347             pRecentMenu = dynamic_cast< PopupMenu * >( pTKMenu->GetMenu() );
348         maOpenButton.SetPopupMenu( pRecentMenu );
349     }
350 }
351 
initBackground()352 void BackingWindow::initBackground()
353 {
354     SetBackground();
355 
356     bool bDark = GetSettings().GetStyleSettings().GetHighContrastMode();
357     if( bDark )
358         maWelcomeTextColor = maLabelTextColor = Color( COL_WHITE );
359     else if( mnLayoutStyle == 1 )
360         maWelcomeTextColor = maLabelTextColor = Color( COL_BLACK );
361     else
362         maWelcomeTextColor = maLabelTextColor = Color( 0x26, 0x35, 0x42 );
363 
364     Color aTextBGColor( bDark ? COL_BLACK : COL_WHITE );
365 
366     // select image set
367     ImageContainerRes aRes( FwkResId( bDark ? RES_BACKING_IMAGES_HC : RES_BACKING_IMAGES ) );
368 
369     // scale middle segment
370     Size aMiddleSize;
371     if( !! maBackgroundMiddle )
372         aMiddleSize = maBackgroundMiddle.GetSizePixel();
373     // load middle segment
374     maBackgroundMiddle = BitmapEx( FwkResId( BMP_BACKING_BACKGROUND_MIDDLE ) );
375     // and scale it to previous size
376     if( aMiddleSize.Width() && aMiddleSize.Height() )
377         maBackgroundMiddle.Scale( aMiddleSize );
378 
379     if( GetSettings().GetLayoutRTL() )
380     {
381         // replace images by RTL versions
382         maBackgroundLeft = BitmapEx( FwkResId( BMP_BACKING_BACKGROUND_RTL_RIGHT ) );
383         maBackgroundRight = BitmapEx( FwkResId( BMP_BACKING_BACKGROUND_RTL_LEFT) );
384     }
385     else
386     {
387         maBackgroundLeft = BitmapEx( FwkResId( BMP_BACKING_BACKGROUND_LEFT ) );
388         maBackgroundRight = BitmapEx( FwkResId( BMP_BACKING_BACKGROUND_RIGHT ) );
389     }
390     maToolbox.SetItemImage( nItemId_Extensions, BitmapEx( FwkResId( BMP_BACKING_EXT ) ) );
391 //###    maToolbox.SetItemImage( nItemId_Reg, BitmapEx( FwkResId( BMP_BACKING_REG ) ) );
392     maToolbox.SetItemImage( nItemId_Info, BitmapEx( FwkResId( BMP_BACKING_INFO ) ) );
393     maToolbox.SetItemImage( nItemId_TplRep, BitmapEx( FwkResId( BMP_BACKING_TPLREP ) ) );
394 
395     maWelcome.SetControlForeground( maWelcomeTextColor );
396     maWelcome.SetBackground();
397     maProduct.SetControlForeground( maWelcomeTextColor );
398     maProduct.SetBackground();
399 
400     if( mnLayoutStyle == 1 )
401     {
402         if( Application::GetSettings().GetLayoutRTL() )
403             mnBtnPos = maBackgroundRight.GetSizePixel().Width() + 40;
404         else
405             mnBtnPos = maBackgroundLeft.GetSizePixel().Width() + 40;
406     }
407 
408     // get icon images from fwk resource and set them on the appropriate buttons
409     loadImage( FwkResId( BMP_BACKING_WRITER ), maWriterButton );
410     loadImage( FwkResId( BMP_BACKING_CALC ), maCalcButton );
411     loadImage( FwkResId( BMP_BACKING_IMPRESS ), maImpressButton );
412     loadImage( FwkResId( BMP_BACKING_DRAW ), maDrawButton );
413     loadImage( FwkResId( BMP_BACKING_DATABASE ), maDBButton );
414     loadImage( FwkResId( BMP_BACKING_FORMULA ), maMathButton );
415     loadImage( FwkResId( BMP_BACKING_OPENFILE ), maOpenButton );
416     loadImage( FwkResId( BMP_BACKING_OPENTEMPLATE ), maTemplateButton );
417 
418     maOpenButton.SetMenuMode( MENUBUTTON_MENUMODE_TIMED );
419     maOpenButton.SetActivateHdl( LINK( this, BackingWindow, ActivateHdl ) );
420 }
421 
initControls()422 void BackingWindow::initControls()
423 {
424     if( mbInitControls )
425         return;
426 
427     mbInitControls = true;
428 
429     // calculate dialog size
430     // begin with background bitmap
431     maControlRect = Rectangle( Point(), maBackgroundLeft.GetSizePixel() );
432     maControlRect.Left() += nShadowLeft;
433     maControlRect.Right() -= nShadowRight;
434     maControlRect.Top() += nShadowTop;
435     maControlRect.Bottom() -= nShadowBottom;
436 
437     long nYPos = 0;
438     // set bigger welcome string
439     maWelcome.SetText( maWelcomeString );
440     maTextFont = GetSettings().GetStyleSettings().GetLabelFont();
441     maTextFont.SetSize( Size( 0, 18 ) );
442     maTextFont.SetWeight( WEIGHT_BOLD );
443     maWelcome.SetFont( maTextFont );
444     // get metric to get correct width factor and adjust
445     long nW = (maWelcome.GetFontMetric().GetWidth()*95)/100;
446     maTextFont.SetSize( Size( nW, 18 ) );
447 
448     maWelcome.SetFont( maTextFont );
449     maWelcome.SetControlFont( maTextFont );
450     maWelcomeSize = Size( maWelcome.GetTextWidth( maWelcomeString ), maWelcome.GetTextHeight() );
451     maWelcomeSize.Width() = (maWelcomeSize.Width() * 20)/19;
452 
453     nYPos += (maWelcomeSize.Height()*3)/2;
454 
455     if( maControlRect.GetWidth() < mnBtnPos + maWelcomeSize.Width() + 20 )
456         maControlRect.Right() = maControlRect.Left() + maWelcomeSize.Width() + mnBtnPos + 20;
457 
458     nYPos += maWelcomeSize.Height();
459 
460     // set product string
461     maTextFont.SetSize( Size( 0, 30 ) );
462     maProduct.SetFont( maTextFont );
463 
464     // get metric to get correct width factor and adjust
465     nW = (maProduct.GetFontMetric().GetWidth()*95)/100;
466     maTextFont.SetSize( Size( nW, 28 ) );
467 
468     maProduct.SetFont( maTextFont );
469     maProduct.SetControlFont( maTextFont );
470     maProduct.SetText( maProductString );
471     maProductSize = Size( maProduct.GetTextWidth( maProductString ), maProduct.GetTextHeight() );
472     maProductSize.Width() = (maProductSize.Width() * 20)/19;
473 
474     if( maControlRect.GetWidth() < maProductSize.Width() + mnBtnPos + 10 )
475         maControlRect.Right() = maControlRect.Left() + maProductSize.Width() + mnBtnPos + 10;
476 
477     if( mnLayoutStyle == 1 )
478     {
479         maWelcome.Show();
480         maProduct.Show();
481     }
482 
483     nYPos += (maProductSize.Height()*3)/2;
484 
485     // set a slightly larger font than normal labels on the texts
486     maTextFont.SetSize( Size( 0, 11 ) );
487     maTextFont.SetWeight( WEIGHT_NORMAL );
488 
489     // collect the URLs of the entries in the File/New menu
490     SvtModuleOptions	aModuleOptions;
491     std::set< rtl::OUString > aFileNewAppsAvailable;
492     SvtDynamicMenuOptions aOpt;
493     Sequence < Sequence < PropertyValue > > aNewMenu = aOpt.GetMenu( E_NEWMENU );
494     const rtl::OUString sURLKey( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
495 
496     const Sequence< PropertyValue >* pNewMenu = aNewMenu.getConstArray();
497     const Sequence< PropertyValue >* pNewMenuEnd = aNewMenu.getConstArray() + aNewMenu.getLength();
498     for ( ; pNewMenu != pNewMenuEnd; ++pNewMenu )
499     {
500         comphelper::SequenceAsHashMap aEntryItems( *pNewMenu );
501         rtl::OUString sURL( aEntryItems.getUnpackedValueOrDefault( sURLKey, rtl::OUString() ) );
502         if ( sURL.getLength() )
503             aFileNewAppsAvailable.insert( sURL );
504     }
505 
506     // create mnemonics on the fly, preregister the mnemonics of the menu
507     MnemonicGenerator aMnemns;
508     maTemplateString = MnemonicGenerator::EraseAllMnemonicChars( maTemplateString );
509     maOpenString = MnemonicGenerator::EraseAllMnemonicChars( maOpenString );
510 
511     SystemWindow* pSysWin = GetSystemWindow();
512     if( pSysWin )
513     {
514         MenuBar* pMBar = pSysWin->GetMenuBar();
515         if( pMBar )
516         {
517             for( sal_uInt16 i = 0; i < pMBar->GetItemCount(); i++ )
518             {
519                 sal_uInt16 nItemId = pMBar->GetItemId( i );
520                 String aItemText( pMBar->GetItemText( nItemId ) );
521                 if( aItemText.Len() )
522                     aMnemns.RegisterMnemonic( aItemText );
523             }
524         }
525     }
526 
527     // layout the buttons
528     layoutButton( WRITER_URL, 0, aFileNewAppsAvailable,
529                   aModuleOptions, SvtModuleOptions::E_SWRITER,
530                   maWriterButton, aMnemns );
531     layoutButton( DRAW_URL, 1, aFileNewAppsAvailable,
532                   aModuleOptions, SvtModuleOptions::E_SDRAW,
533                   maDrawButton, aMnemns );
534     nYPos += maButtonImageSize.Height() + 10;
535     layoutButton( CALC_URL, 0, aFileNewAppsAvailable,
536                   aModuleOptions, SvtModuleOptions::E_SCALC,
537                   maCalcButton, aMnemns );
538     layoutButton( BASE_URL, 1, aFileNewAppsAvailable,
539                   aModuleOptions, SvtModuleOptions::E_SDATABASE,
540                   maDBButton, aMnemns );
541     nYPos += maButtonImageSize.Height() + 10;
542     layoutButton( IMPRESS_WIZARD_URL, 0, aFileNewAppsAvailable,
543                   aModuleOptions, SvtModuleOptions::E_SIMPRESS,
544                   maImpressButton, aMnemns );
545     layoutButton( MATH_URL, 1, aFileNewAppsAvailable,
546                   aModuleOptions, SvtModuleOptions::E_SMATH,
547                   maMathButton, aMnemns );
548 
549     nYPos += 3*maButtonImageSize.Height() / 2;
550 
551     layoutButton( NULL, 0, aFileNewAppsAvailable,
552                   aModuleOptions, SvtModuleOptions::E_SWRITER,
553                   maOpenButton, aMnemns, maOpenString );
554     layoutButton( NULL, 1, aFileNewAppsAvailable,
555                   aModuleOptions, SvtModuleOptions::E_SWRITER,
556                   maTemplateButton, aMnemns, maTemplateString );
557     nYPos += 10;
558 
559     DBG_ASSERT( nYPos < maControlRect.GetHeight(), "misformatting !" );
560     if( mnColumnWidth[0] + mnColumnWidth[1] + mnBtnPos + 20 > maControlRect.GetWidth() )
561         maControlRect.Right() = maControlRect.Left() + mnColumnWidth[0] + mnColumnWidth[1] + mnBtnPos + 20;
562 
563     mnTextColumnWidth[0] = mnColumnWidth[0];
564     mnTextColumnWidth[1] = mnColumnWidth[1];
565 
566     if( mnTextColumnWidth[1] > mnTextColumnWidth[0] )
567     {
568         mnColumnWidth[0]     = mnColumnWidth[1];
569         mnTextColumnWidth[0] = mnTextColumnWidth[1];
570     }
571     else
572     {
573         mnColumnWidth[1]     = mnColumnWidth[0];
574         mnTextColumnWidth[1] = mnTextColumnWidth[0];
575     }
576     if( maControlRect.GetWidth() < maControlRect.GetHeight() * 3 / 2 )
577     {
578         maControlRect.Right() = maControlRect.Left() + maControlRect.GetHeight() * 3 / 2;
579         long nDelta = (maControlRect.GetWidth() - mnBtnPos - mnColumnWidth[1] - mnColumnWidth[0] - 20);
580         mnColumnWidth[0] += nDelta/2;
581         mnColumnWidth[1] += nDelta/2;
582     }
583 
584     maToolbox.SetSelectHdl( LINK( this, BackingWindow, ToolboxHdl ) );
585     if( mnLayoutStyle == 0 )
586         maToolbox.Show();
587 
588     // scale middle map to formatted width
589     Size aMiddleSegmentSize( maControlRect.GetSize().Width() + nShadowLeft + nShadowRight,
590                              maBackgroundMiddle.GetSizePixel().Height() );
591 
592     long nLW = maBackgroundLeft.GetSizePixel().Width();
593     long nRW = maBackgroundRight.GetSizePixel().Width();
594     if( aMiddleSegmentSize.Width() > nLW + nRW )
595     {
596         aMiddleSegmentSize.Width() -= nLW;
597         aMiddleSegmentSize.Width() -= nRW;
598         maBackgroundMiddle.Scale( aMiddleSegmentSize );
599     }
600     else
601         maBackgroundMiddle = BitmapEx();
602 
603     Resize();
604 
605     maWriterButton.GrabFocus();
606 }
607 
loadImage(const ResId & i_rId,PushButton & i_rButton)608 void BackingWindow::loadImage( const ResId& i_rId, PushButton& i_rButton )
609 {
610     BitmapEx aBmp( i_rId );
611     Size aImgSize( aBmp.GetSizePixel() );
612     if( aImgSize.Width() > maButtonImageSize.Width() )
613         maButtonImageSize.Width() = aImgSize.Width();
614     if( aImgSize.Height() > maButtonImageSize.Height() )
615         maButtonImageSize.Height() = aImgSize.Height();
616     i_rButton.SetModeImage( aBmp );
617 }
618 
layoutButton(const char * i_pURL,int nColumn,const std::set<rtl::OUString> & i_rURLS,SvtModuleOptions & i_rOpt,SvtModuleOptions::EModule i_eMod,PushButton & i_rBtn,MnemonicGenerator & i_rMnemns,const String & i_rStr)619 void BackingWindow::layoutButton(
620                           const char* i_pURL, int nColumn,
621                           const std::set<rtl::OUString>& i_rURLS,
622                           SvtModuleOptions& i_rOpt, SvtModuleOptions::EModule i_eMod,
623                           PushButton& i_rBtn,
624                           MnemonicGenerator& i_rMnemns,
625                           const String& i_rStr
626                           )
627 {
628     rtl::OUString aURL( rtl::OUString::createFromAscii( i_pURL ? i_pURL : "" ) );
629     // setup button
630     i_rBtn.SetPaintTransparent( sal_True );
631     i_rBtn.SetClickHdl( LINK( this, BackingWindow, ClickHdl ) );
632     if( i_pURL && (! i_rOpt.IsModuleInstalled( i_eMod ) || i_rURLS.find( aURL ) == i_rURLS.end()) )
633     {
634         i_rBtn.Enable( sal_False );
635     }
636 
637     // setup text
638     i_rBtn.SetFont( maTextFont );
639     i_rBtn.SetControlFont( maTextFont );
640     String aText( i_rStr.Len() ? i_rStr : SvFileInformationManager::GetDescription( INetURLObject( aURL ) ) );
641     i_rMnemns.CreateMnemonic( aText );
642     i_rBtn.SetText( aText );
643 
644     long nTextWidth = i_rBtn.GetTextWidth( i_rBtn.GetText() );
645 
646     nTextWidth += maButtonImageSize.Width() + 8; // add some fuzz to be on the safe side
647     if( nColumn >= 0 && nColumn < static_cast<int>(sizeof(mnColumnWidth)/sizeof(mnColumnWidth[0])) )
648     {
649         if( nTextWidth > mnColumnWidth[nColumn] )
650             mnColumnWidth[nColumn] = nTextWidth;
651     }
652 
653     i_rBtn.SetImageAlign( IMAGEALIGN_LEFT );
654     // show the controls
655     i_rBtn.Show();
656 }
657 
Paint(const Rectangle &)658 void BackingWindow::Paint( const Rectangle& )
659 {
660 	Resize();
661 
662     Wallpaper aBack( GetSettings().GetStyleSettings().GetWorkspaceGradient() );
663     Region aClip( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) );
664     Rectangle aBmpRect(maControlRect);
665     aBmpRect.Left()   -= nShadowLeft;
666     aBmpRect.Top()    -= nShadowTop;
667     aBmpRect.Right()  += nShadowRight;
668     aBmpRect.Bottom() += nShadowBottom;
669     aClip.Exclude( aBmpRect );
670     Push( PUSH_CLIPREGION );
671     IntersectClipRegion( aClip );
672     DrawWallpaper( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ), aBack );
673     Pop();
674 
675     VirtualDevice aDev( *this );
676     aDev.EnableRTL( IsRTLEnabled() );
677     aDev.SetOutputSizePixel( aBmpRect.GetSize() );
678     Point aOffset( Point( 0, 0 ) - aBmpRect.TopLeft() );
679     aDev.DrawWallpaper( Rectangle( aOffset, GetOutputSizePixel() ), aBack );
680 
681     // draw bitmap
682     Point aTL( 0, 0 );
683     aDev.DrawBitmapEx( aTL, maBackgroundLeft );
684     aTL.X() += maBackgroundLeft.GetSizePixel().Width();
685     if( !!maBackgroundMiddle )
686     {
687         aDev.DrawBitmapEx( aTL, maBackgroundMiddle );
688         aTL.X() += maBackgroundMiddle.GetSizePixel().Width();
689     }
690     aDev.DrawBitmapEx( aTL, maBackgroundRight );
691 
692     DrawOutDev( aBmpRect.TopLeft(), aBmpRect.GetSize(),
693                 Point( 0, 0 ), aBmpRect.GetSize(),
694                 aDev );
695 }
696 
Notify(NotifyEvent & rNEvt)697 long BackingWindow::Notify( NotifyEvent& rNEvt )
698 {
699     if( rNEvt.GetType() == EVENT_KEYINPUT )
700     {
701         if( ! mpAccExec )
702         {
703             mpAccExec = svt::AcceleratorExecute::createAcceleratorHelper();
704             mpAccExec->init( comphelper::getProcessServiceFactory(), mxFrame);
705         }
706 
707         const KeyEvent* pEvt = rNEvt.GetKeyEvent();
708         const KeyCode& rKeyCode(pEvt->GetKeyCode());
709         if( pEvt && mpAccExec->execute(rKeyCode) )
710             return 1;
711         // #i110344# extrawurst: specialized arrow key control
712         if( rKeyCode.GetModifier() == 0 )
713         {
714             if( rKeyCode.GetCode() == KEY_RIGHT )
715             {
716                 if( maWriterButton.HasFocus() )
717                     maDrawButton.GrabFocus();
718                 else if( maCalcButton.HasFocus() )
719                     maDBButton.GrabFocus();
720                 else if( maImpressButton.HasFocus() )
721                     maMathButton.GrabFocus();
722                 else if( maOpenButton.HasFocus() )
723                     maTemplateButton.GrabFocus();
724                 return 1;
725             }
726             else if( rKeyCode.GetCode() == KEY_LEFT )
727             {
728                 if( maDrawButton.HasFocus() )
729                     maWriterButton.GrabFocus();
730                 else if( maDBButton.HasFocus() )
731                     maCalcButton.GrabFocus();
732                 else if( maMathButton.HasFocus() )
733                     maImpressButton.GrabFocus();
734                 else if( maTemplateButton.HasFocus() )
735                     maOpenButton.GrabFocus();
736                 return 1;
737             }
738             else if( rKeyCode.GetCode() == KEY_UP )
739             {
740                 // first column
741                 if( maOpenButton.HasFocus() )
742                     maImpressButton.GrabFocus();
743                 else if( maImpressButton.HasFocus() )
744                     maCalcButton.GrabFocus();
745                 else if( maCalcButton.HasFocus() )
746                     maWriterButton.GrabFocus();
747                 // second column
748                 else if( maTemplateButton.HasFocus() )
749                     maMathButton.GrabFocus();
750                 else if( maMathButton.HasFocus() )
751                     maDBButton.GrabFocus();
752                 else if( maDBButton.HasFocus() )
753                     maDrawButton.GrabFocus();
754                 return 1;
755             }
756             else if( rKeyCode.GetCode() == KEY_DOWN )
757             {
758                 // first column
759                 if( maWriterButton.HasFocus() )
760                     maCalcButton.GrabFocus();
761                 else if( maCalcButton.HasFocus() )
762                     maImpressButton.GrabFocus();
763                 else if( maImpressButton.HasFocus() )
764                     maOpenButton.GrabFocus();
765                 // second column
766                 else if( maDrawButton.HasFocus() )
767                     maDBButton.GrabFocus();
768                 else if( maDBButton.HasFocus() )
769                     maMathButton.GrabFocus();
770                 else if( maMathButton.HasFocus() )
771                     maTemplateButton.GrabFocus();
772                 return 1;
773             }
774         }
775     }
776     return Window::Notify( rNEvt );
777 }
778 
setOwningFrame(const com::sun::star::uno::Reference<com::sun::star::frame::XFrame> & xFrame)779 void BackingWindow::setOwningFrame( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& xFrame )
780 {
781     mxFrame = xFrame;
782     if( ! mbInitControls )
783         initControls();
784 }
785 
Resize()786 void BackingWindow::Resize()
787 {
788     Size aWindowSize( GetSizePixel() );
789     Size aControlSize = maControlRect.GetSize();
790     maControlRect = Rectangle( Point( (aWindowSize.Width() - aControlSize.Width()) / 2,
791                                       (aWindowSize.Height() - aControlSize.Height()) / 2 ),
792                                aControlSize );
793 
794     maToolbox.calcMinSize();
795     Size aTBSize( maToolbox.getMinSize() );
796     Point aTBPos( maControlRect.Left() + mnBtnPos,
797                   maControlRect.Bottom() - aTBSize.Height() - 10 );
798     if( Application::GetSettings().GetLayoutRTL() )
799         aTBPos.X() = maControlRect.Right() - aTBSize.Width() - mnBtnPos;
800     maToolbox.SetPosSizePixel( aTBPos, aTBSize );
801 
802     // #i93631# squeeze controls so they fit into the box
803     // this can be necessary due to application font height which has small deviations
804     // from the size set
805     const long nWDelta    = maWelcomeSize.Height();
806     const long nW2Delta   = (maWelcomeSize.Height()*3)/2;
807     const long nPDelta    = (maProductSize.Height()*3)/2;
808     const long nBDelta    = maButtonImageSize.Height() + 10;
809     const long nB2Delta   = 3*maButtonImageSize.Height()/2;
810     const long nLastDelta = maButtonImageSize.Height();
811     long nDiff = 0;
812     while( ( maControlRect.Top()   +
813                  (nWDelta - nDiff) +
814                  (nW2Delta- nDiff) +
815                  (nPDelta - nDiff) +
816              3 * (nBDelta - nDiff) +
817                  (nB2Delta- nDiff) +
818                  nLastDelta
819             ) > aTBPos.Y() )
820     {
821         nDiff++;
822     }
823 
824     long nYPos = maControlRect.Top();
825     nYPos += nW2Delta - nDiff;
826     maWelcome.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ),
827                                 Size( maControlRect.GetWidth() - mnBtnPos - 5, (maWelcomeSize.Height()*20)/19 ) );
828     nYPos += nWDelta - nDiff;
829     maProduct.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( maControlRect.GetWidth() - mnBtnPos - 5, (maProductSize.Height()*20)/19 ) );
830     nYPos += nPDelta - nDiff;
831 
832     nYPos += nWDelta/2 - nDiff;
833 
834     if( mnLayoutStyle != 1 )
835         nYPos = maControlRect.Top() + mnBtnTop;
836 
837     maWriterButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
838     maDrawButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
839     nYPos += nBDelta - nDiff;
840     maCalcButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
841     maDBButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
842     nYPos += nBDelta - nDiff;
843     maImpressButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
844     maMathButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
845 
846     nYPos += nB2Delta - nDiff;
847     maOpenButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
848     maTemplateButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
849 
850 	if( !IsInPaint())
851 		Invalidate();
852 }
853 
IMPL_LINK(BackingWindow,ToolboxHdl,void *,EMPTYARG)854 IMPL_LINK( BackingWindow, ToolboxHdl, void*, EMPTYARG )
855 {
856     const char* pNodePath = NULL;
857     const char* pNode = NULL;
858 
859     switch( maToolbox.GetCurItemId() )
860     {
861     case nItemId_Extensions:
862         pNodePath = "/org.openoffice.Office.Common/Help/StartCenter";
863         pNode = "AddFeatureURL";
864         break;
865     case nItemId_Info:
866         pNodePath = "/org.openoffice.Office.Common/Help/StartCenter";
867         pNode = "InfoURL";
868         break;
869     case nItemId_TplRep:
870         pNodePath = "/org.openoffice.Office.Common/Help/StartCenter";
871         pNode = "TemplateRepositoryURL";
872         break;
873     default:
874         break;
875     }
876     if( pNodePath && pNode )
877     {
878         try
879         {
880             Reference<lang::XMultiServiceFactory> xConfig( comphelper::getProcessServiceFactory()->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY);
881             if( xConfig.is() )
882             {
883                 Sequence<Any> args(1);
884                 PropertyValue val(
885                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("nodepath") ),
886                     0,
887                     Any(rtl::OUString::createFromAscii(pNodePath)),
888                     PropertyState_DIRECT_VALUE);
889                 args.getArray()[0] <<= val;
890                 Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY);
891                 if( xNameAccess.is() )
892                 {
893                     rtl::OUString sURL;
894                     //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
895                     Any value( xNameAccess->getByName(rtl::OUString::createFromAscii(pNode)) );
896                     sURL = value.get<rtl::OUString> ();
897 
898                     // extend the URLs with Office locale argument
899                     INetURLObject aURLObj( sURL );
900 
901                     rtl::OUString sParam = aURLObj.GetParam();
902                     rtl::OUStringBuffer aURLBuf( sParam );
903                     if ( sParam.getLength() > 0 )
904                         aURLBuf.appendAscii( "&" );
905                     aURLBuf.appendAscii( "lang=" );
906 
907                     // read locale from configuration
908                     ::rtl::OUString sLocale;
909                     ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup");
910                     ::rtl::OUString sRelPath = ::rtl::OUString::createFromAscii("L10N");
911                     ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooLocale");
912 
913                     try
914                     {
915                         ::comphelper::ConfigurationHelper::readDirectKey(comphelper::getProcessServiceFactory(),
916                                                                          sPackage,
917                                                                          sRelPath,
918                                                                          sKey,
919                                                                          ::comphelper::ConfigurationHelper::E_READONLY) >>= sLocale;
920                     }
921                     catch(const com::sun::star::uno::RuntimeException& exRun)
922                         { throw exRun; }
923                     catch(const com::sun::star::uno::Exception&)
924                     { sLocale = ::rtl::OUString::createFromAscii("en-US"); }
925 
926                     aURLBuf.append(sLocale);
927 
928                     sParam = aURLBuf.makeStringAndClear();
929 
930                     aURLObj.SetParam( sParam );
931                     sURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
932 
933                     Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
934                         com::sun::star::system::SystemShellExecute::create(
935                             ::comphelper::getProcessComponentContext() ) );
936                     //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
937                     xSystemShellExecute->execute( sURL, rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS);
938                 }
939             }
940         }
941         catch (Exception& )
942         {
943         }
944     }
945 
946     return 0;
947 }
948 
IMPL_LINK(BackingWindow,ClickHdl,Button *,pButton)949 IMPL_LINK( BackingWindow, ClickHdl, Button*, pButton )
950 {
951     // dispatch the appropriate URL and end the dialog
952     if( pButton == &maWriterButton )
953         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(WRITER_URL) ) );
954     else if( pButton == &maCalcButton )
955         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(CALC_URL) ) );
956     else if( pButton == &maImpressButton )
957         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(IMPRESS_WIZARD_URL) ) );
958     else if( pButton == &maDrawButton )
959         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(DRAW_URL) ) );
960     else if( pButton == &maDBButton )
961         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(BASE_URL) ) );
962     else if( pButton == &maMathButton )
963         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(MATH_URL) ) );
964     else if( pButton == &maOpenButton )
965     {
966         Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );
967 
968         Sequence< com::sun::star::beans::PropertyValue > aArgs(1);
969         PropertyValue* pArg = aArgs.getArray();
970         pArg[0].Name = rtl::OUString::createFromAscii("Referer");
971         pArg[0].Value <<= rtl::OUString::createFromAscii("private:user");
972 
973         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(OPEN_URL) ), rtl::OUString(), xFrame, aArgs );
974     }
975     else if( pButton == &maTemplateButton )
976     {
977         Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );
978 
979         Sequence< com::sun::star::beans::PropertyValue > aArgs(1);
980         PropertyValue* pArg = aArgs.getArray();
981         pArg[0].Name = rtl::OUString::createFromAscii("Referer");
982         pArg[0].Value <<= rtl::OUString::createFromAscii("private:user");
983 
984         dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(TEMPLATE_URL) ), rtl::OUString(), xFrame, aArgs );
985     }
986     return 0;
987 }
988 
989 
IMPL_LINK(BackingWindow,ActivateHdl,Button *,pButton)990 IMPL_LINK( BackingWindow, ActivateHdl, Button*, pButton )
991 {
992     if( pButton == &maOpenButton )
993         prepareRecentFileMenu();
994     return 0;
995 }
996 
997 struct ImplDelayedDispatch
998 {
999     Reference< XDispatch >      xDispatch;
1000     com::sun::star::util::URL   aDispatchURL;
1001     Sequence< PropertyValue >   aArgs;
1002 
ImplDelayedDispatchImplDelayedDispatch1003     ImplDelayedDispatch( const Reference< XDispatch >& i_xDispatch,
1004                          const com::sun::star::util::URL& i_rURL,
1005                          const Sequence< PropertyValue >& i_rArgs )
1006     : xDispatch( i_xDispatch ),
1007       aDispatchURL( i_rURL ),
1008       aArgs( i_rArgs )
1009     {
1010     }
~ImplDelayedDispatchImplDelayedDispatch1011     ~ImplDelayedDispatch() {}
1012 };
1013 
implDispatchDelayed(void *,void * pArg)1014 static long implDispatchDelayed( void*, void* pArg )
1015 {
1016     struct ImplDelayedDispatch* pDispatch = reinterpret_cast<ImplDelayedDispatch*>(pArg);
1017     try
1018     {
1019         pDispatch->xDispatch->dispatch( pDispatch->aDispatchURL, pDispatch->aArgs );
1020     }
1021     catch( Exception )
1022     {
1023     }
1024 
1025     // clean up
1026     delete pDispatch;
1027 
1028     return 0;
1029 }
1030 
dispatchURL(const rtl::OUString & i_rURL,const rtl::OUString & rTarget,const Reference<XDispatchProvider> & i_xProv,const Sequence<PropertyValue> & i_rArgs)1031 void BackingWindow::dispatchURL( const rtl::OUString& i_rURL,
1032                                  const rtl::OUString& rTarget,
1033                                  const Reference< XDispatchProvider >& i_xProv,
1034                                  const Sequence< PropertyValue >& i_rArgs )
1035 {
1036     // if no special dispatch provider is given, get the desktop
1037     Reference< XDispatchProvider > xProvider( i_xProv.is() ? i_xProv : mxDesktopDispatchProvider );
1038 
1039     // check for dispatch provider
1040     if( !xProvider.is())
1041         return;
1042 
1043     // get an URL transformer to clean up the URL
1044     com::sun::star::util::URL aDispatchURL;
1045     aDispatchURL.Complete = i_rURL;
1046 
1047     Reference < com::sun::star::util::XURLTransformer > xURLTransformer(
1048         comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer") ),
1049         com::sun::star::uno::UNO_QUERY );
1050     if ( xURLTransformer.is() )
1051     {
1052         try
1053         {
1054             // clean up the URL
1055             xURLTransformer->parseStrict( aDispatchURL );
1056             // get a Dispatch for the URL and target
1057             Reference< XDispatch > xDispatch(
1058                 xProvider->queryDispatch( aDispatchURL, rTarget, 0 )
1059                 );
1060             // dispatch the URL
1061             if ( xDispatch.is() )
1062             {
1063                 ImplDelayedDispatch* pDisp = new ImplDelayedDispatch( xDispatch, aDispatchURL, i_rArgs );
1064                 sal_uLong nEventId = 0;
1065                 if( ! Application::PostUserEvent( nEventId, Link( NULL, implDispatchDelayed ), pDisp ) )
1066                     delete pDisp; // event could not be posted for unknown reason, at least don't leak
1067             }
1068         }
1069         catch ( com::sun::star::uno::RuntimeException& )
1070         {
1071             throw;
1072         }
1073         catch ( com::sun::star::uno::Exception& )
1074         {
1075         }
1076     }
1077 }
1078 
1079