xref: /trunk/main/cui/source/tabpages/macroass.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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