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