xref: /AOO41X/main/cui/source/tabpages/macroass.cxx (revision 2ee96f1cdb99d49425d866b1ec4c5567f37285e6)
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