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 Wallpaper aBack( GetSettings().GetStyleSettings().GetWorkspaceGradient() ); 701 Region aClip( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) ); 702 Rectangle aBmpRect(maControlRect); 703 aBmpRect.Left() -= nShadowLeft; 704 aBmpRect.Top() -= nShadowTop; 705 aBmpRect.Right() += nShadowRight; 706 aBmpRect.Bottom() += nShadowBottom; 707 aClip.Exclude( aBmpRect ); 708 Push( PUSH_CLIPREGION ); 709 IntersectClipRegion( aClip ); 710 DrawWallpaper( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ), aBack ); 711 Pop(); 712 713 VirtualDevice aDev( *this ); 714 aDev.EnableRTL( IsRTLEnabled() ); 715 aDev.SetOutputSizePixel( aBmpRect.GetSize() ); 716 Point aOffset( Point( 0, 0 ) - aBmpRect.TopLeft() ); 717 aDev.DrawWallpaper( Rectangle( aOffset, GetOutputSizePixel() ), aBack ); 718 719 // draw bitmap 720 Point aTL( 0, 0 ); 721 aDev.DrawBitmapEx( aTL, maBackgroundLeft ); 722 aTL.X() += maBackgroundLeft.GetSizePixel().Width(); 723 if( !!maBackgroundMiddle ) 724 { 725 aDev.DrawBitmapEx( aTL, maBackgroundMiddle ); 726 aTL.X() += maBackgroundMiddle.GetSizePixel().Width(); 727 } 728 aDev.DrawBitmapEx( aTL, maBackgroundRight ); 729 730 DrawOutDev( aBmpRect.TopLeft(), aBmpRect.GetSize(), 731 Point( 0, 0 ), aBmpRect.GetSize(), 732 aDev ); 733 } 734 735 long BackingWindow::Notify( NotifyEvent& rNEvt ) 736 { 737 if( rNEvt.GetType() == EVENT_KEYINPUT ) 738 { 739 if( ! mpAccExec ) 740 { 741 mpAccExec = svt::AcceleratorExecute::createAcceleratorHelper(); 742 mpAccExec->init( comphelper::getProcessServiceFactory(), mxFrame); 743 } 744 745 const KeyEvent* pEvt = rNEvt.GetKeyEvent(); 746 const KeyCode& rKeyCode(pEvt->GetKeyCode()); 747 if( pEvt && mpAccExec->execute(rKeyCode) ) 748 return 1; 749 // #i110344# extrawurst: specialized arrow key control 750 if( rKeyCode.GetModifier() == 0 ) 751 { 752 if( rKeyCode.GetCode() == KEY_RIGHT ) 753 { 754 if( maWriterButton.HasFocus() ) 755 maDrawButton.GrabFocus(); 756 else if( maCalcButton.HasFocus() ) 757 maDBButton.GrabFocus(); 758 else if( maImpressButton.HasFocus() ) 759 maMathButton.GrabFocus(); 760 else if( maOpenButton.HasFocus() ) 761 maTemplateButton.GrabFocus(); 762 return 1; 763 } 764 else if( rKeyCode.GetCode() == KEY_LEFT ) 765 { 766 if( maDrawButton.HasFocus() ) 767 maWriterButton.GrabFocus(); 768 else if( maDBButton.HasFocus() ) 769 maCalcButton.GrabFocus(); 770 else if( maMathButton.HasFocus() ) 771 maImpressButton.GrabFocus(); 772 else if( maTemplateButton.HasFocus() ) 773 maOpenButton.GrabFocus(); 774 return 1; 775 } 776 else if( rKeyCode.GetCode() == KEY_UP ) 777 { 778 // first column 779 if( maOpenButton.HasFocus() ) 780 maImpressButton.GrabFocus(); 781 else if( maImpressButton.HasFocus() ) 782 maCalcButton.GrabFocus(); 783 else if( maCalcButton.HasFocus() ) 784 maWriterButton.GrabFocus(); 785 // second column 786 else if( maTemplateButton.HasFocus() ) 787 maMathButton.GrabFocus(); 788 else if( maMathButton.HasFocus() ) 789 maDBButton.GrabFocus(); 790 else if( maDBButton.HasFocus() ) 791 maDrawButton.GrabFocus(); 792 return 1; 793 } 794 else if( rKeyCode.GetCode() == KEY_DOWN ) 795 { 796 // first column 797 if( maWriterButton.HasFocus() ) 798 maCalcButton.GrabFocus(); 799 else if( maCalcButton.HasFocus() ) 800 maImpressButton.GrabFocus(); 801 else if( maImpressButton.HasFocus() ) 802 maOpenButton.GrabFocus(); 803 // second column 804 else if( maDrawButton.HasFocus() ) 805 maDBButton.GrabFocus(); 806 else if( maDBButton.HasFocus() ) 807 maMathButton.GrabFocus(); 808 else if( maMathButton.HasFocus() ) 809 maTemplateButton.GrabFocus(); 810 return 1; 811 } 812 } 813 } 814 return Window::Notify( rNEvt ); 815 } 816 817 void BackingWindow::setOwningFrame( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& xFrame ) 818 { 819 mxFrame = xFrame; 820 if( ! mbInitControls ) 821 initControls(); 822 } 823 824 void BackingWindow::Resize() 825 { 826 Size aWindowSize( GetSizePixel() ); 827 Size aControlSize = maControlRect.GetSize(); 828 maControlRect = Rectangle( Point( (aWindowSize.Width() - aControlSize.Width()) / 2, 829 (aWindowSize.Height() - aControlSize.Height()) / 2 ), 830 aControlSize ); 831 832 maToolbox.calcMinSize(); 833 Size aTBSize( maToolbox.getMinSize() ); 834 Point aTBPos( maControlRect.Left() + mnBtnPos, 835 maControlRect.Bottom() - aTBSize.Height() - 10 ); 836 if( Application::GetSettings().GetLayoutRTL() ) 837 aTBPos.X() = maControlRect.Right() - aTBSize.Width() - mnBtnPos; 838 maToolbox.SetPosSizePixel( aTBPos, aTBSize ); 839 840 // #i93631# squeeze controls so they fit into the box 841 // this can be necessary due to application font height which has small deviations 842 // from the size set 843 const long nWDelta = maWelcomeSize.Height(); 844 const long nW2Delta = (maWelcomeSize.Height()*3)/2; 845 const long nPDelta = (maProductSize.Height()*3)/2; 846 const long nBDelta = maButtonImageSize.Height() + 10; 847 const long nB2Delta = 3*maButtonImageSize.Height()/2; 848 const long nLastDelta = maButtonImageSize.Height(); 849 long nDiff = 0; 850 while( ( maControlRect.Top() + 851 (nWDelta - nDiff) + 852 (nW2Delta- nDiff) + 853 (nPDelta - nDiff) + 854 3 * (nBDelta - nDiff) + 855 (nB2Delta- nDiff) + 856 nLastDelta 857 ) > aTBPos.Y() ) 858 { 859 nDiff++; 860 } 861 862 long nYPos = maControlRect.Top(); 863 nYPos += nW2Delta - nDiff; 864 maWelcome.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), 865 Size( maControlRect.GetWidth() - mnBtnPos - 5, (maWelcomeSize.Height()*20)/19 ) ); 866 nYPos += nWDelta - nDiff; 867 maProduct.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( maControlRect.GetWidth() - mnBtnPos - 5, (maProductSize.Height()*20)/19 ) ); 868 nYPos += nPDelta - nDiff; 869 870 nYPos += nWDelta/2 - nDiff; 871 872 if( mnLayoutStyle != 1 ) 873 nYPos = maControlRect.Top() + mnBtnTop; 874 875 maWriterButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) ); 876 maDrawButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) ); 877 nYPos += nBDelta - nDiff; 878 maCalcButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) ); 879 maDBButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) ); 880 nYPos += nBDelta - nDiff; 881 maImpressButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) ); 882 maMathButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) ); 883 884 nYPos += nB2Delta - nDiff; 885 maOpenButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) ); 886 maTemplateButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) ); 887 } 888 889 IMPL_LINK( BackingWindow, ToolboxHdl, void*, EMPTYARG ) 890 { 891 const char* pNodePath = NULL; 892 const char* pNode = NULL; 893 894 switch( maToolbox.GetCurItemId() ) 895 { 896 case nItemId_Extensions: 897 pNodePath = "/org.openoffice.Office.Common/Help/StartCenter"; 898 pNode = "AddFeatureURL"; 899 break; 900 case nItemId_Info: 901 pNodePath = "/org.openoffice.Office.Common/Help/StartCenter"; 902 pNode = "InfoURL"; 903 break; 904 case nItemId_TplRep: 905 pNodePath = "/org.openoffice.Office.Common/Help/StartCenter"; 906 pNode = "TemplateRepositoryURL"; 907 break; 908 default: 909 break; 910 } 911 if( pNodePath && pNode ) 912 { 913 try 914 { 915 Reference<lang::XMultiServiceFactory> xConfig( comphelper::getProcessServiceFactory()->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY); 916 if( xConfig.is() ) 917 { 918 Sequence<Any> args(1); 919 PropertyValue val( 920 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("nodepath") ), 921 0, 922 Any(rtl::OUString::createFromAscii(pNodePath)), 923 PropertyState_DIRECT_VALUE); 924 args.getArray()[0] <<= val; 925 Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY); 926 if( xNameAccess.is() ) 927 { 928 rtl::OUString sURL; 929 //throws css::container::NoSuchElementException, css::lang::WrappedTargetException 930 Any value( xNameAccess->getByName(rtl::OUString::createFromAscii(pNode)) ); 931 sURL = value.get<rtl::OUString> (); 932 933 // extend the URLs with Office locale argument 934 INetURLObject aURLObj( sURL ); 935 936 rtl::OUString sParam = aURLObj.GetParam(); 937 rtl::OUStringBuffer aURLBuf( sParam ); 938 if ( sParam.getLength() > 0 ) 939 aURLBuf.appendAscii( "&" ); 940 aURLBuf.appendAscii( "lang=" ); 941 942 // read locale from configuration 943 ::rtl::OUString sLocale; 944 ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup"); 945 ::rtl::OUString sRelPath = ::rtl::OUString::createFromAscii("L10N"); 946 ::rtl::OUString sKey = ::rtl::OUString::createFromAscii("ooLocale"); 947 948 try 949 { 950 ::comphelper::ConfigurationHelper::readDirectKey(comphelper::getProcessServiceFactory(), 951 sPackage, 952 sRelPath, 953 sKey, 954 ::comphelper::ConfigurationHelper::E_READONLY) >>= sLocale; 955 } 956 catch(const com::sun::star::uno::RuntimeException& exRun) 957 { throw exRun; } 958 catch(const com::sun::star::uno::Exception&) 959 { sLocale = ::rtl::OUString::createFromAscii("en-US"); } 960 961 aURLBuf.append(sLocale); 962 963 sParam = aURLBuf.makeStringAndClear(); 964 965 aURLObj.SetParam( sParam ); 966 sURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE ); 967 968 Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute( 969 comphelper::getProcessServiceFactory()->createInstance( 970 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.system.SystemShellExecute" ) ) ), 971 UNO_QUERY_THROW); 972 //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException 973 xSystemShellExecute->execute( sURL, rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS); 974 } 975 } 976 } 977 catch (Exception& ) 978 { 979 } 980 } 981 982 return 0; 983 } 984 985 IMPL_LINK( BackingWindow, ClickHdl, Button*, pButton ) 986 { 987 // dispatch the appropriate URL and end the dialog 988 if( pButton == &maWriterButton ) 989 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(WRITER_URL) ) ); 990 else if( pButton == &maCalcButton ) 991 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(CALC_URL) ) ); 992 else if( pButton == &maImpressButton ) 993 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(IMPRESS_WIZARD_URL) ) ); 994 else if( pButton == &maDrawButton ) 995 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(DRAW_URL) ) ); 996 else if( pButton == &maDBButton ) 997 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(BASE_URL) ) ); 998 else if( pButton == &maMathButton ) 999 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(MATH_URL) ) ); 1000 else if( pButton == &maOpenButton ) 1001 { 1002 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 1003 1004 Sequence< com::sun::star::beans::PropertyValue > aArgs(1); 1005 PropertyValue* pArg = aArgs.getArray(); 1006 pArg[0].Name = rtl::OUString::createFromAscii("Referer"); 1007 pArg[0].Value <<= rtl::OUString::createFromAscii("private:user"); 1008 1009 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(OPEN_URL) ), rtl::OUString(), xFrame, aArgs ); 1010 } 1011 else if( pButton == &maTemplateButton ) 1012 { 1013 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 1014 1015 Sequence< com::sun::star::beans::PropertyValue > aArgs(1); 1016 PropertyValue* pArg = aArgs.getArray(); 1017 pArg[0].Name = rtl::OUString::createFromAscii("Referer"); 1018 pArg[0].Value <<= rtl::OUString::createFromAscii("private:user"); 1019 1020 dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(TEMPLATE_URL) ), rtl::OUString(), xFrame, aArgs ); 1021 } 1022 return 0; 1023 } 1024 1025 IMPL_LINK( BackingWindow, SelectHdl, Button*, pButton ) 1026 { 1027 if( pButton == &maOpenButton ) 1028 { 1029 sal_Int32 nItem = sal_Int32(maOpenButton.GetCurItemId())-1; 1030 if( nItem >= 0 && nItem < sal_Int32(maRecentFiles.size()) ) 1031 { 1032 Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY ); 1033 dispatchURL( maRecentFiles[nItem].aTargetURL, rtl::OUString(), xFrame, maRecentFiles[nItem].aArgSeq ); 1034 } 1035 } 1036 return 0; 1037 } 1038 1039 IMPL_LINK( BackingWindow, ActivateHdl, Button*, pButton ) 1040 { 1041 if( pButton == &maOpenButton ) 1042 prepareRecentFileMenu(); 1043 return 0; 1044 } 1045 1046 struct ImplDelayedDispatch 1047 { 1048 Reference< XDispatch > xDispatch; 1049 com::sun::star::util::URL aDispatchURL; 1050 Sequence< PropertyValue > aArgs; 1051 1052 ImplDelayedDispatch( const Reference< XDispatch >& i_xDispatch, 1053 const com::sun::star::util::URL& i_rURL, 1054 const Sequence< PropertyValue >& i_rArgs ) 1055 : xDispatch( i_xDispatch ), 1056 aDispatchURL( i_rURL ), 1057 aArgs( i_rArgs ) 1058 { 1059 } 1060 ~ImplDelayedDispatch() {} 1061 }; 1062 1063 static long implDispatchDelayed( void*, void* pArg ) 1064 { 1065 struct ImplDelayedDispatch* pDispatch = reinterpret_cast<ImplDelayedDispatch*>(pArg); 1066 try 1067 { 1068 pDispatch->xDispatch->dispatch( pDispatch->aDispatchURL, pDispatch->aArgs ); 1069 } 1070 catch( Exception ) 1071 { 1072 } 1073 1074 // clean up 1075 delete pDispatch; 1076 1077 return 0; 1078 } 1079 1080 void BackingWindow::dispatchURL( const rtl::OUString& i_rURL, 1081 const rtl::OUString& rTarget, 1082 const Reference< XDispatchProvider >& i_xProv, 1083 const Sequence< PropertyValue >& i_rArgs ) 1084 { 1085 // if no special dispatch provider is given, get the desktop 1086 Reference< XDispatchProvider > xProvider( i_xProv.is() ? i_xProv : mxDesktopDispatchProvider ); 1087 1088 // check for dispatch provider 1089 if( !xProvider.is()) 1090 return; 1091 1092 // get an URL transformer to clean up the URL 1093 com::sun::star::util::URL aDispatchURL; 1094 aDispatchURL.Complete = i_rURL; 1095 1096 Reference < com::sun::star::util::XURLTransformer > xURLTransformer( 1097 comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer") ), 1098 com::sun::star::uno::UNO_QUERY ); 1099 if ( xURLTransformer.is() ) 1100 { 1101 try 1102 { 1103 // clean up the URL 1104 xURLTransformer->parseStrict( aDispatchURL ); 1105 // get a Dispatch for the URL and target 1106 Reference< XDispatch > xDispatch( 1107 xProvider->queryDispatch( aDispatchURL, rTarget, 0 ) 1108 ); 1109 // dispatch the URL 1110 if ( xDispatch.is() ) 1111 { 1112 ImplDelayedDispatch* pDisp = new ImplDelayedDispatch( xDispatch, aDispatchURL, i_rArgs ); 1113 sal_uLong nEventId = 0; 1114 if( ! Application::PostUserEvent( nEventId, Link( NULL, implDispatchDelayed ), pDisp ) ) 1115 delete pDisp; // event could not be posted for unknown reason, at least don't leak 1116 } 1117 } 1118 catch ( com::sun::star::uno::RuntimeException& ) 1119 { 1120 throw; 1121 } 1122 catch ( com::sun::star::uno::Exception& ) 1123 { 1124 } 1125 } 1126 } 1127 1128