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