1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_cui.hxx" 30 31 #define ITEMID_MACRO 0 32 #include <svl/macitem.hxx> 33 #undef ITEMID_MACRO 34 35 #include "macroass.hxx" 36 37 #include <basic/basmgr.hxx> 38 #include <dialmgr.hxx> 39 #include <svx/dialogs.hrc> 40 #define _SVSTDARR_STRINGSDTOR 41 #include <svl/svstdarr.hxx> 42 43 #include <svtools/svmedit.hxx> 44 #include "cfgutil.hxx" 45 #include <sfx2/app.hxx> 46 #include <sfx2/evntconf.hxx> 47 #include <sfx2/objsh.hxx> 48 #include "macroass.hrc" 49 #include "cuires.hrc" 50 #include <vcl/fixed.hxx> 51 #include "headertablistbox.hxx" 52 53 using ::com::sun::star::uno::Reference; 54 using ::com::sun::star::frame::XFrame; 55 56 class _SfxMacroTabPage_Impl 57 { 58 public: 59 _SfxMacroTabPage_Impl( void ); 60 ~_SfxMacroTabPage_Impl(); 61 62 String maStaticMacroLBLabel; 63 PushButton* pAssignPB; 64 PushButton* pDeletePB; 65 String* pStrEvent; 66 String* pAssignedMacro; 67 _HeaderTabListBox* pEventLB; 68 SfxConfigGroupListBox_Impl* pGroupLB; 69 FixedText* pFT_MacroLBLabel; 70 SfxConfigFunctionListBox_Impl* pMacroLB; 71 72 FixedText* pMacroFT; 73 String* pMacroStr; 74 75 sal_Bool bReadOnly; 76 Timer maFillGroupTimer; 77 sal_Bool bGotEvents; 78 }; 79 80 _SfxMacroTabPage_Impl::_SfxMacroTabPage_Impl( void ) : 81 pAssignPB( NULL ), 82 pDeletePB( NULL ), 83 pStrEvent( NULL ), 84 pAssignedMacro( NULL ), 85 pEventLB( NULL ), 86 pGroupLB( NULL ), 87 pFT_MacroLBLabel( NULL ), 88 pMacroLB( NULL ), 89 pMacroFT( NULL ), 90 pMacroStr( NULL ), 91 bReadOnly( sal_False ), 92 bGotEvents( sal_False ) 93 { 94 } 95 96 _SfxMacroTabPage_Impl::~_SfxMacroTabPage_Impl() 97 { 98 delete pAssignPB; 99 delete pDeletePB; 100 delete pStrEvent; 101 delete pAssignedMacro; 102 delete pEventLB; 103 delete pGroupLB; 104 delete pMacroLB; 105 delete pFT_MacroLBLabel; 106 delete pMacroFT; 107 delete pMacroStr; 108 } 109 110 111 static sal_uInt16 __FAR_DATA aPageRg[] = { 112 SID_ATTR_MACROITEM, SID_ATTR_MACROITEM, 113 0 114 }; 115 116 // Achtung im Code wird dieses Array direkt (0, 1, ...) indiziert 117 static long nTabs[] = 118 { 119 2, // Number of Tabs 120 0, 90 121 }; 122 123 #define TAB_WIDTH_MIN 10 124 125 // IDs for items in HeaderBar of EventLB 126 #define ITEMID_EVENT 1 127 #define ITMEID_ASSMACRO 2 128 129 130 #define LB_EVENTS_ITEMPOS 1 131 #define LB_MACROS_ITEMPOS 2 132 133 String ConvertToUIName_Impl( SvxMacro *pMacro ) 134 { 135 String aName( pMacro->GetMacName() ); 136 String aEntry; 137 if ( ! pMacro->GetLanguage().EqualsAscii("JavaScript") ) 138 { 139 sal_uInt16 nCount = aName.GetTokenCount('.'); 140 aEntry = aName.GetToken( nCount-1, '.' ); 141 if ( nCount > 2 ) 142 { 143 aEntry += '('; 144 aEntry += aName.GetToken( 0, '.' ); 145 aEntry += '.'; 146 aEntry += aName.GetToken( nCount-2, '.' ); 147 aEntry += ')'; 148 } 149 return aEntry; 150 } 151 else 152 return aName; 153 } 154 155 void _SfxMacroTabPage::EnableButtons() 156 { 157 // Solange die Eventbox leer ist, nichts tun 158 const SvLBoxEntry* pE = mpImpl->pEventLB->GetListBox().FirstSelected(); 159 if ( pE ) 160 { 161 // Gebundenes Macro holen 162 const SvxMacro* pM = aTbl.Get( (sal_uInt16)(sal_uLong) pE->GetUserData() ); 163 mpImpl->pDeletePB->Enable( 0 != pM && !mpImpl->bReadOnly ); 164 165 String sEventMacro; 166 sEventMacro = ((SvLBoxString*)pE->GetItem( LB_MACROS_ITEMPOS ))->GetText(); 167 168 String sScriptURI = mpImpl->pMacroLB->GetSelectedScriptURI(); 169 mpImpl->pAssignPB->Enable( !mpImpl->bReadOnly && !sScriptURI.EqualsIgnoreCaseAscii( sEventMacro ) ); 170 } 171 else 172 mpImpl->pAssignPB->Enable( sal_False ); 173 } 174 175 _SfxMacroTabPage::_SfxMacroTabPage( Window* pParent, const ResId& rResId, const SfxItemSet& rAttrSet ) 176 : SfxTabPage( pParent, rResId, rAttrSet ) 177 178 { 179 mpImpl = new _SfxMacroTabPage_Impl; 180 } 181 182 _SfxMacroTabPage::~_SfxMacroTabPage() 183 { 184 DELETEZ( mpImpl ); 185 } 186 187 void _SfxMacroTabPage::AddEvent( const String & rEventName, sal_uInt16 nEventId ) 188 { 189 String sTmp( rEventName ); 190 sTmp += '\t'; 191 192 // falls die Tabelle schon gueltig ist 193 SvxMacro* pM = aTbl.Get( nEventId ); 194 if( pM ) 195 { 196 String sNew( ConvertToUIName_Impl( pM ) ); 197 sTmp += sNew; 198 } 199 200 SvLBoxEntry* pE = mpImpl->pEventLB->GetListBox().InsertEntry( sTmp ); 201 pE->SetUserData( reinterpret_cast< void* >( sal::static_int_cast< sal_IntPtr >( nEventId )) ); 202 } 203 204 void _SfxMacroTabPage::ScriptChanged() 205 { 206 // neue Bereiche und deren Funktionen besorgen 207 { 208 mpImpl->pGroupLB->Show(); 209 mpImpl->pMacroLB->Show(); 210 mpImpl->pMacroFT->SetText( *mpImpl->pMacroStr ); 211 } 212 213 EnableButtons(); 214 } 215 216 sal_Bool _SfxMacroTabPage::FillItemSet( SfxItemSet& rSet ) 217 { 218 SvxMacroItem aItem( GetWhich( aPageRg[0] ) ); 219 ((SvxMacroTableDtor&)aItem.GetMacroTable()) = aTbl; 220 221 const SfxPoolItem* pItem; 222 if( SFX_ITEM_SET != GetItemSet().GetItemState( aItem.Which(), sal_True, &pItem ) 223 || aItem != *(SvxMacroItem*)pItem ) 224 { 225 rSet.Put( aItem ); 226 return sal_True; 227 } 228 return sal_False; 229 } 230 231 void _SfxMacroTabPage::PageCreated (SfxAllItemSet aSet) 232 { 233 const SfxPoolItem* pEventsItem; 234 if( !mpImpl->bGotEvents && SFX_ITEM_SET == aSet.GetItemState( SID_EVENTCONFIG, sal_True, &pEventsItem ) ) 235 { 236 mpImpl->bGotEvents = sal_True; 237 const SfxEventNamesList& rList = ((SfxEventNamesItem*)pEventsItem)->GetEvents(); 238 for ( sal_uInt16 nNo = 0; nNo < rList.Count(); ++nNo ) 239 { 240 const SfxEventName *pOwn = rList.GetObject(nNo); 241 AddEvent( pOwn->maUIName, pOwn->mnId ); 242 } 243 } 244 } 245 246 void _SfxMacroTabPage::Reset( const SfxItemSet& rSet ) 247 { 248 const SfxPoolItem* pItem; 249 if( SFX_ITEM_SET == rSet.GetItemState( GetWhich( aPageRg[0] ), sal_True, &pItem )) 250 aTbl = ((SvxMacroItem*)pItem)->GetMacroTable(); 251 252 const SfxPoolItem* pEventsItem; 253 if( !mpImpl->bGotEvents && SFX_ITEM_SET == rSet.GetItemState( SID_EVENTCONFIG, sal_True, &pEventsItem ) ) 254 { 255 mpImpl->bGotEvents = sal_True; 256 const SfxEventNamesList& rList = ((SfxEventNamesItem*)pEventsItem)->GetEvents(); 257 for ( sal_uInt16 nNo = 0; nNo < rList.Count(); ++nNo ) 258 { 259 const SfxEventName *pOwn = rList.GetObject(nNo); 260 AddEvent( pOwn->maUIName, pOwn->mnId ); 261 } 262 } 263 264 FillEvents(); 265 266 SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox(); 267 SvLBoxEntry* pE = rListBox.GetEntry( 0 ); 268 if( pE ) 269 rListBox.SetCurEntry( pE ); 270 } 271 272 sal_Bool _SfxMacroTabPage::IsReadOnly() const 273 { 274 return mpImpl->bReadOnly; 275 } 276 277 IMPL_STATIC_LINK( _SfxMacroTabPage, SelectEvent_Impl, SvTabListBox*, EMPTYARG ) 278 { 279 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl; 280 SvHeaderTabListBox& rListBox = pImpl->pEventLB->GetListBox(); 281 SvLBoxEntry* pE = rListBox.FirstSelected(); 282 sal_uLong nPos; 283 if( !pE || LISTBOX_ENTRY_NOTFOUND == 284 ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) ) 285 { 286 DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" ); 287 return 0; 288 } 289 290 pThis->ScriptChanged(); 291 pThis->EnableButtons(); 292 return 0; 293 } 294 295 IMPL_STATIC_LINK( _SfxMacroTabPage, SelectGroup_Impl, ListBox*, EMPTYARG ) 296 { 297 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl; 298 String sSel( pImpl->pGroupLB->GetGroup() ); 299 pImpl->pGroupLB->GroupSelected(); 300 const String sScriptURI = pImpl->pMacroLB->GetSelectedScriptURI(); 301 String aLabelText; 302 if( sScriptURI.Len() > 0 ) 303 aLabelText = pImpl->maStaticMacroLBLabel; 304 pImpl->pFT_MacroLBLabel->SetText( aLabelText ); 305 306 pThis->EnableButtons(); 307 return 0; 308 } 309 310 IMPL_STATIC_LINK( _SfxMacroTabPage, SelectMacro_Impl, ListBox*, EMPTYARG ) 311 { 312 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl; 313 pImpl->pMacroLB->FunctionSelected(); 314 pThis->EnableButtons(); 315 return 0; 316 } 317 318 IMPL_STATIC_LINK( _SfxMacroTabPage, AssignDeleteHdl_Impl, PushButton*, pBtn ) 319 { 320 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl; 321 SvHeaderTabListBox& rListBox = pImpl->pEventLB->GetListBox(); 322 SvLBoxEntry* pE = rListBox.FirstSelected(); 323 sal_uLong nPos; 324 if( !pE || LISTBOX_ENTRY_NOTFOUND == 325 ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) ) 326 { 327 DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" ); 328 return 0; 329 } 330 331 const sal_Bool bAssEnabled = pBtn != pImpl->pDeletePB && pImpl->pAssignPB->IsEnabled(); 332 333 // aus der Tabelle entfernen 334 sal_uInt16 nEvent = (sal_uInt16)(sal_uLong)pE->GetUserData(); 335 SvxMacro *pRemoveMacro = pThis->aTbl.Remove( nEvent ); 336 delete pRemoveMacro; 337 338 String sScriptURI; 339 if( bAssEnabled ) 340 { 341 sScriptURI = pImpl->pMacroLB->GetSelectedScriptURI(); 342 if( sScriptURI.CompareToAscii( "vnd.sun.star.script:", 20 ) == COMPARE_EQUAL ) 343 { 344 pThis->aTbl.Insert( 345 nEvent, new SvxMacro( sScriptURI, String::CreateFromAscii( SVX_MACRO_LANGUAGE_SF ) ) ); 346 } 347 else 348 { 349 OSL_ENSURE( false, "_SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" ); 350 pThis->aTbl.Insert( 351 nEvent, new SvxMacro( sScriptURI, String::CreateFromAscii( SVX_MACRO_LANGUAGE_STARBASIC ) ) ); 352 } 353 } 354 355 pImpl->pEventLB->SetUpdateMode( sal_False ); 356 pE->ReplaceItem( new SvLBoxString( pE, 0, sScriptURI ), LB_MACROS_ITEMPOS ); 357 rListBox.GetModel()->InvalidateEntry( pE ); 358 rListBox.Select( pE ); 359 rListBox.MakeVisible( pE ); 360 rListBox.SetUpdateMode( sal_True ); 361 362 pThis->EnableButtons(); 363 return 0; 364 } 365 366 IMPL_STATIC_LINK( _SfxMacroTabPage, TimeOut_Impl, Timer*, EMPTYARG ) 367 { 368 // FillMacroList() can take a long time -> show wait cursor and disable input 369 SfxTabDialog* pTabDlg = pThis->GetTabDialog(); 370 // perhaps the tabpage is part of a SingleTabDialog then pTabDlg == NULL 371 if ( pTabDlg ) 372 { 373 pTabDlg->EnterWait(); 374 pTabDlg->EnableInput( sal_False ); 375 } 376 pThis->FillMacroList(); 377 if ( pTabDlg ) 378 { 379 pTabDlg->EnableInput( sal_True ); 380 pTabDlg->LeaveWait(); 381 } 382 return 0; 383 } 384 385 void _SfxMacroTabPage::InitAndSetHandler() 386 { 387 // Handler installieren 388 SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox(); 389 HeaderBar& rHeaderBar = mpImpl->pEventLB->GetHeaderBar(); 390 Link aLnk(STATIC_LINK(this, _SfxMacroTabPage, AssignDeleteHdl_Impl )); 391 mpImpl->pMacroLB->SetDoubleClickHdl( aLnk ); 392 mpImpl->pDeletePB->SetClickHdl( aLnk ); 393 mpImpl->pAssignPB->SetClickHdl( aLnk ); 394 rListBox.SetDoubleClickHdl( aLnk ); 395 396 rListBox.SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectEvent_Impl )); 397 mpImpl->pGroupLB->SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectGroup_Impl )); 398 mpImpl->pMacroLB->SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectMacro_Impl )); 399 400 rListBox.SetSelectionMode( SINGLE_SELECTION ); 401 rListBox.SetTabs( &nTabs[0], MAP_APPFONT ); 402 Size aSize( nTabs[ 2 ], 0 ); 403 rHeaderBar.InsertItem( ITEMID_EVENT, *mpImpl->pStrEvent, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() ); 404 aSize.Width() = 1764; // don't know what, so 42^2 is best to use... 405 rHeaderBar.InsertItem( ITMEID_ASSMACRO, *mpImpl->pAssignedMacro, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() ); 406 rListBox.SetSpaceBetweenEntries( 0 ); 407 408 mpImpl->pEventLB->Show(); 409 mpImpl->pEventLB->ConnectElements(); 410 411 mpImpl->pEventLB->Enable( sal_True ); 412 mpImpl->pGroupLB->Enable( sal_True ); 413 mpImpl->pMacroLB->Enable( sal_True ); 414 415 mpImpl->pGroupLB->SetFunctionListBox( mpImpl->pMacroLB ); 416 417 mpImpl->maFillGroupTimer.SetTimeoutHdl( STATIC_LINK( this, _SfxMacroTabPage, TimeOut_Impl ) ); 418 mpImpl->maFillGroupTimer.SetTimeout( 0 ); 419 mpImpl->maFillGroupTimer.Start(); 420 } 421 422 void _SfxMacroTabPage::FillMacroList() 423 { 424 mpImpl->pGroupLB->Init( 425 ::com::sun::star::uno::Reference< 426 ::com::sun::star::lang::XMultiServiceFactory >(), 427 GetFrame(), 428 ::rtl::OUString() ); 429 } 430 431 void _SfxMacroTabPage::FillEvents() 432 { 433 SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox(); 434 435 sal_uLong nEntryCnt = rListBox.GetEntryCount(); 436 437 // Events aus der Tabelle holen und die EventListBox entsprechen fuellen 438 for( sal_uLong n = 0 ; n < nEntryCnt ; ++n ) 439 { 440 SvLBoxEntry* pE = rListBox.GetEntry( n ); 441 if( pE ) 442 { 443 SvLBoxString* pLItem = ( SvLBoxString* ) pE->GetItem( LB_MACROS_ITEMPOS ); 444 DBG_ASSERT( pLItem && SV_ITEM_ID_LBOXSTRING == pLItem->IsA(), "_SfxMacroTabPage::FillEvents(): no LBoxString" ); 445 446 String sOld( pLItem->GetText() ); 447 String sNew; 448 sal_uInt16 nEventId = ( sal_uInt16 ) ( sal_uLong ) pE->GetUserData(); 449 if( aTbl.IsKeyValid( nEventId ) ) 450 sNew = ConvertToUIName_Impl( aTbl.Get( nEventId ) ); 451 452 if( sOld != sNew ) 453 { 454 pE->ReplaceItem( new SvLBoxString( pE, 0, sNew ), LB_MACROS_ITEMPOS ); 455 rListBox.GetModel()->InvalidateEntry( pE ); 456 } 457 } 458 } 459 } 460 461 SfxMacroTabPage::SfxMacroTabPage( Window* pParent, const ResId& rResId, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet ) 462 : _SfxMacroTabPage( pParent, rResId, rSet ) 463 { 464 mpImpl->pStrEvent = new String( CUI_RES( STR_EVENT ) ); 465 mpImpl->pAssignedMacro = new String( CUI_RES( STR_ASSMACRO ) ); 466 mpImpl->pEventLB = new _HeaderTabListBox( this, CUI_RES( LB_EVENT ) ); 467 mpImpl->pAssignPB = new PushButton( this, CUI_RES( PB_ASSIGN ) ); 468 mpImpl->pDeletePB = new PushButton( this, CUI_RES( PB_DELETE ) ); 469 mpImpl->pMacroFT = new FixedText( this, CUI_RES( FT_MACRO ) ); 470 mpImpl->pGroupLB = new SfxConfigGroupListBox_Impl( this, CUI_RES( LB_GROUP ) ); 471 mpImpl->pFT_MacroLBLabel = new FixedText( this, CUI_RES( FT_LABEL4LB_MACROS ) ); 472 mpImpl->maStaticMacroLBLabel= mpImpl->pFT_MacroLBLabel->GetText(); 473 mpImpl->pMacroLB = new SfxConfigFunctionListBox_Impl( this, CUI_RES( LB_MACROS ) ); 474 mpImpl->pMacroStr = new String( CUI_RES( STR_MACROS ) ); 475 476 FreeResource(); 477 478 SetFrame( rxDocumentFrame ); 479 480 InitAndSetHandler(); 481 482 ScriptChanged(); 483 } 484 485 SfxTabPage* SfxMacroTabPage::Create( Window* pParent, const SfxItemSet& rAttrSet ) 486 { 487 return new SfxMacroTabPage( pParent, CUI_RES( RID_SVXPAGE_EVENTASSIGN ), NULL, rAttrSet ); 488 } 489 490 SfxMacroAssignDlg::SfxMacroAssignDlg( Window* pParent, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet ) 491 : SfxSingleTabDialog( pParent, rSet, 0 ) 492 { 493 SfxTabPage* pPage = SfxMacroTabPage::Create( this, rSet ); 494 pPage->SetFrame( rxDocumentFrame ); 495 SetTabPage( pPage ); 496 } 497 498 SfxMacroAssignDlg::~SfxMacroAssignDlg() 499 { 500 } 501 502 503