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