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