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