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
_SfxMacroTabPage_Impl(void)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
~_SfxMacroTabPage_Impl()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
ConvertToUIName_Impl(SvxMacro * pMacro)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
EnableButtons()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
_SfxMacroTabPage(Window * pParent,const ResId & rResId,const SfxItemSet & rAttrSet)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
~_SfxMacroTabPage()178 _SfxMacroTabPage::~_SfxMacroTabPage()
179 {
180 DELETEZ( mpImpl );
181 }
182
AddEvent(const String & rEventName,sal_uInt16 nEventId)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
ScriptChanged()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
FillItemSet(SfxItemSet & rSet)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
PageCreated(SfxAllItemSet aSet)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
Reset(const SfxItemSet & rSet)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
IsReadOnly() const268 sal_Bool _SfxMacroTabPage::IsReadOnly() const
269 {
270 return mpImpl->bReadOnly;
271 }
272
IMPL_STATIC_LINK(_SfxMacroTabPage,SelectEvent_Impl,SvTabListBox *,EMPTYARG)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
IMPL_STATIC_LINK(_SfxMacroTabPage,SelectGroup_Impl,ListBox *,EMPTYARG)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
IMPL_STATIC_LINK(_SfxMacroTabPage,SelectMacro_Impl,ListBox *,EMPTYARG)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
IMPL_STATIC_LINK(_SfxMacroTabPage,AssignDeleteHdl_Impl,PushButton *,pBtn)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
IMPL_STATIC_LINK(_SfxMacroTabPage,TimeOut_Impl,Timer *,EMPTYARG)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
InitAndSetHandler()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
FillMacroList()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
FillEvents()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
SfxMacroTabPage(Window * pParent,const ResId & rResId,const Reference<XFrame> & rxDocumentFrame,const SfxItemSet & rSet)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
Create(Window * pParent,const SfxItemSet & rAttrSet)481 SfxTabPage* SfxMacroTabPage::Create( Window* pParent, const SfxItemSet& rAttrSet )
482 {
483 return new SfxMacroTabPage( pParent, CUI_RES( RID_SVXPAGE_EVENTASSIGN ), NULL, rAttrSet );
484 }
485
SfxMacroAssignDlg(Window * pParent,const Reference<XFrame> & rxDocumentFrame,const SfxItemSet & rSet)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
~SfxMacroAssignDlg()494 SfxMacroAssignDlg::~SfxMacroAssignDlg()
495 {
496 }
497
498
499