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