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