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