Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #define ITEMID_MACRO 0
21 : #include <svl/macitem.hxx>
22 : #undef ITEMID_MACRO
23 :
24 : #include "macroass.hxx"
25 :
26 : #include <basic/basmgr.hxx>
27 : #include <comphelper/string.hxx>
28 : #include <dialmgr.hxx>
29 : #include <svx/dialogs.hrc>
30 : #include <svtools/svmedit.hxx>
31 : #include "cfgutil.hxx"
32 : #include <sfx2/app.hxx>
33 : #include <sfx2/evntconf.hxx>
34 : #include <sfx2/objsh.hxx>
35 : #include "macroass.hrc"
36 : #include "cuires.hrc"
37 : #include <vcl/fixed.hxx>
38 : #include "headertablistbox.hxx"
39 : #include "svtools/svlbitm.hxx"
40 : #include "svtools/treelistentry.hxx"
41 :
42 : using ::com::sun::star::uno::Reference;
43 : using ::com::sun::star::frame::XFrame;
44 :
45 : class _SfxMacroTabPage_Impl
46 : {
47 : public:
48 : _SfxMacroTabPage_Impl( void );
49 : ~_SfxMacroTabPage_Impl();
50 :
51 : String maStaticMacroLBLabel;
52 : PushButton* pAssignPB;
53 : PushButton* pDeletePB;
54 : String* pStrEvent;
55 : String* pAssignedMacro;
56 : _HeaderTabListBox* pEventLB;
57 : SfxConfigGroupListBox_Impl* pGroupLB;
58 : FixedText* pFT_MacroLBLabel;
59 : SfxConfigFunctionListBox_Impl* pMacroLB;
60 :
61 : FixedText* pMacroFT;
62 : String* pMacroStr;
63 :
64 : sal_Bool bReadOnly;
65 : Timer maFillGroupTimer;
66 : sal_Bool bGotEvents;
67 : bool m_bDummyActivated; ///< has this tab page already been activated
68 : };
69 :
70 0 : _SfxMacroTabPage_Impl::_SfxMacroTabPage_Impl( void ) :
71 : pAssignPB( NULL ),
72 : pDeletePB( NULL ),
73 : pStrEvent( NULL ),
74 : pAssignedMacro( NULL ),
75 : pEventLB( NULL ),
76 : pGroupLB( NULL ),
77 : pFT_MacroLBLabel( NULL ),
78 : pMacroLB( NULL ),
79 : pMacroFT( NULL ),
80 : pMacroStr( NULL ),
81 : bReadOnly( sal_False ),
82 : bGotEvents( sal_False )
83 0 : , m_bDummyActivated(false)
84 : {
85 0 : }
86 :
87 0 : _SfxMacroTabPage_Impl::~_SfxMacroTabPage_Impl()
88 : {
89 0 : delete pAssignPB;
90 0 : delete pDeletePB;
91 0 : delete pStrEvent;
92 0 : delete pAssignedMacro;
93 0 : delete pEventLB;
94 0 : delete pGroupLB;
95 0 : delete pMacroLB;
96 0 : delete pFT_MacroLBLabel;
97 0 : delete pMacroFT;
98 0 : delete pMacroStr;
99 0 : }
100 :
101 :
102 : static sal_uInt16 aPageRg[] = {
103 : SID_ATTR_MACROITEM, SID_ATTR_MACROITEM,
104 : 0
105 : };
106 :
107 : // attention, this array is indexed directly (0, 1, ...) in the code
108 : static long nTabs[] =
109 : {
110 : 2, // Number of Tabs
111 : 0, 90
112 : };
113 :
114 : // IDs for items in HeaderBar of EventLB
115 : #define ITEMID_EVENT 1
116 : #define ITMEID_ASSMACRO 2
117 :
118 :
119 : #define LB_MACROS_ITEMPOS 2
120 :
121 0 : String ConvertToUIName_Impl( SvxMacro *pMacro )
122 : {
123 0 : String aName( pMacro->GetMacName() );
124 0 : String aEntry;
125 0 : if ( pMacro->GetLanguage() != "JavaScript" )
126 : {
127 0 : sal_uInt16 nCount = comphelper::string::getTokenCount(aName, '.');
128 0 : aEntry = aName.GetToken( nCount-1, '.' );
129 0 : if ( nCount > 2 )
130 : {
131 0 : aEntry += '(';
132 0 : aEntry += aName.GetToken( 0, '.' );
133 0 : aEntry += '.';
134 0 : aEntry += aName.GetToken( nCount-2, '.' );
135 0 : aEntry += ')';
136 : }
137 0 : return aEntry;
138 : }
139 : else
140 0 : return aName;
141 : }
142 :
143 0 : void _SfxMacroTabPage::EnableButtons()
144 : {
145 : // don't do anything as long as the eventbox is empty
146 0 : const SvTreeListEntry* pE = mpImpl->pEventLB->GetListBox().FirstSelected();
147 0 : if ( pE )
148 : {
149 : // get bound macro
150 0 : const SvxMacro* pM = aTbl.Get( (sal_uInt16)(sal_uLong) pE->GetUserData() );
151 0 : mpImpl->pDeletePB->Enable( 0 != pM && !mpImpl->bReadOnly );
152 :
153 0 : String sEventMacro;
154 0 : sEventMacro = ((SvLBoxString*)pE->GetItem( LB_MACROS_ITEMPOS ))->GetText();
155 :
156 0 : String sScriptURI = mpImpl->pMacroLB->GetSelectedScriptURI();
157 0 : mpImpl->pAssignPB->Enable( !mpImpl->bReadOnly && !sScriptURI.EqualsIgnoreCaseAscii( sEventMacro ) );
158 : }
159 : else
160 0 : mpImpl->pAssignPB->Enable( sal_False );
161 0 : }
162 :
163 0 : _SfxMacroTabPage::_SfxMacroTabPage( Window* pParent, const ResId& rResId, const SfxItemSet& rAttrSet )
164 0 : : SfxTabPage( pParent, rResId, rAttrSet )
165 :
166 : {
167 0 : mpImpl = new _SfxMacroTabPage_Impl;
168 0 : }
169 :
170 0 : _SfxMacroTabPage::~_SfxMacroTabPage()
171 : {
172 0 : DELETEZ( mpImpl );
173 0 : }
174 :
175 0 : void _SfxMacroTabPage::AddEvent( const String & rEventName, sal_uInt16 nEventId )
176 : {
177 0 : String sTmp( rEventName );
178 0 : sTmp += '\t';
179 :
180 : // if the table is valid already
181 0 : SvxMacro* pM = aTbl.Get( nEventId );
182 0 : if( pM )
183 : {
184 0 : String sNew( ConvertToUIName_Impl( pM ) );
185 0 : sTmp += sNew;
186 : }
187 :
188 0 : SvTreeListEntry* pE = mpImpl->pEventLB->GetListBox().InsertEntry( sTmp );
189 0 : pE->SetUserData( reinterpret_cast< void* >( sal::static_int_cast< sal_IntPtr >( nEventId )) );
190 0 : }
191 :
192 0 : void _SfxMacroTabPage::ScriptChanged()
193 : {
194 : // get new areas and their functions
195 : {
196 0 : mpImpl->pGroupLB->Show();
197 0 : mpImpl->pMacroLB->Show();
198 0 : mpImpl->pMacroFT->SetText( *mpImpl->pMacroStr );
199 : }
200 :
201 0 : EnableButtons();
202 0 : }
203 :
204 0 : sal_Bool _SfxMacroTabPage::FillItemSet( SfxItemSet& rSet )
205 : {
206 0 : SvxMacroItem aItem( GetWhich( aPageRg[0] ) );
207 0 : ((SvxMacroTableDtor&)aItem.GetMacroTable()) = aTbl;
208 :
209 : const SfxPoolItem* pItem;
210 0 : if( SFX_ITEM_SET != GetItemSet().GetItemState( aItem.Which(), sal_True, &pItem )
211 0 : || aItem != *(SvxMacroItem*)pItem )
212 : {
213 0 : rSet.Put( aItem );
214 0 : return sal_True;
215 : }
216 0 : return sal_False;
217 : }
218 :
219 0 : void _SfxMacroTabPage::ActivatePage( const SfxItemSet& )
220 : {
221 : // fdo#57553 lazily init script providers, because it is annoying if done
222 : // on dialog open (SfxTabDialog::Start_Impl activates all tab pages once!)
223 0 : if (!mpImpl->m_bDummyActivated)
224 : {
225 0 : mpImpl->m_bDummyActivated = true;
226 : }
227 0 : else if (!mpImpl->maFillGroupTimer.GetTimeoutHdl().IsSet())
228 : {
229 0 : mpImpl->maFillGroupTimer.SetTimeoutHdl( STATIC_LINK( this, _SfxMacroTabPage, TimeOut_Impl ) );
230 0 : mpImpl->maFillGroupTimer.SetTimeout( 0 );
231 0 : mpImpl->maFillGroupTimer.Start();
232 : }
233 0 : }
234 :
235 0 : void _SfxMacroTabPage::PageCreated (SfxAllItemSet aSet)
236 : {
237 : const SfxPoolItem* pEventsItem;
238 0 : if( !mpImpl->bGotEvents && SFX_ITEM_SET == aSet.GetItemState( SID_EVENTCONFIG, sal_True, &pEventsItem ) )
239 : {
240 0 : mpImpl->bGotEvents = sal_True;
241 0 : const SfxEventNamesList& rList = ((SfxEventNamesItem*)pEventsItem)->GetEvents();
242 0 : for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
243 : {
244 0 : const SfxEventName *pOwn = rList.at(nNo);
245 0 : AddEvent( pOwn->maUIName, pOwn->mnId );
246 : }
247 : }
248 0 : }
249 :
250 0 : void _SfxMacroTabPage::Reset( const SfxItemSet& rSet )
251 : {
252 : const SfxPoolItem* pItem;
253 0 : if( SFX_ITEM_SET == rSet.GetItemState( GetWhich( aPageRg[0] ), sal_True, &pItem ))
254 0 : aTbl = ((SvxMacroItem*)pItem)->GetMacroTable();
255 :
256 : const SfxPoolItem* pEventsItem;
257 0 : if( !mpImpl->bGotEvents && SFX_ITEM_SET == rSet.GetItemState( SID_EVENTCONFIG, sal_True, &pEventsItem ) )
258 : {
259 0 : mpImpl->bGotEvents = sal_True;
260 0 : const SfxEventNamesList& rList = ((SfxEventNamesItem*)pEventsItem)->GetEvents();
261 0 : for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
262 : {
263 0 : const SfxEventName *pOwn = rList.at(nNo);
264 0 : AddEvent( pOwn->maUIName, pOwn->mnId );
265 : }
266 : }
267 :
268 0 : FillEvents();
269 :
270 0 : SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
271 0 : SvTreeListEntry* pE = rListBox.GetEntry( 0 );
272 0 : if( pE )
273 0 : rListBox.SetCurEntry( pE );
274 0 : }
275 :
276 0 : sal_Bool _SfxMacroTabPage::IsReadOnly() const
277 : {
278 0 : return mpImpl->bReadOnly;
279 : }
280 :
281 0 : IMPL_STATIC_LINK( _SfxMacroTabPage, SelectEvent_Impl, SvTabListBox*, EMPTYARG )
282 : {
283 0 : _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
284 0 : SvHeaderTabListBox& rListBox = pImpl->pEventLB->GetListBox();
285 0 : SvTreeListEntry* pE = rListBox.FirstSelected();
286 : sal_uLong nPos;
287 0 : if( !pE || LISTBOX_ENTRY_NOTFOUND ==
288 0 : ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) )
289 : {
290 : DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
291 0 : return 0;
292 : }
293 :
294 0 : pThis->ScriptChanged();
295 0 : pThis->EnableButtons();
296 0 : return 0;
297 : }
298 :
299 0 : IMPL_STATIC_LINK( _SfxMacroTabPage, SelectGroup_Impl, ListBox*, EMPTYARG )
300 : {
301 0 : _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
302 0 : String sSel( pImpl->pGroupLB->GetGroup() );
303 0 : pImpl->pGroupLB->GroupSelected();
304 0 : const String sScriptURI = pImpl->pMacroLB->GetSelectedScriptURI();
305 0 : String aLabelText;
306 0 : if( sScriptURI.Len() > 0 )
307 0 : aLabelText = pImpl->maStaticMacroLBLabel;
308 0 : pImpl->pFT_MacroLBLabel->SetText( aLabelText );
309 :
310 0 : pThis->EnableButtons();
311 0 : return 0;
312 : }
313 :
314 0 : IMPL_STATIC_LINK( _SfxMacroTabPage, SelectMacro_Impl, ListBox*, EMPTYARG )
315 : {
316 0 : _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
317 0 : pImpl->pMacroLB->FunctionSelected();
318 0 : pThis->EnableButtons();
319 0 : return 0;
320 : }
321 :
322 0 : IMPL_STATIC_LINK( _SfxMacroTabPage, AssignDeleteHdl_Impl, PushButton*, pBtn )
323 : {
324 0 : _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
325 0 : SvHeaderTabListBox& rListBox = pImpl->pEventLB->GetListBox();
326 0 : SvTreeListEntry* pE = rListBox.FirstSelected();
327 : sal_uLong nPos;
328 0 : if( !pE || LISTBOX_ENTRY_NOTFOUND ==
329 0 : ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) )
330 : {
331 : DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
332 0 : return 0;
333 : }
334 :
335 0 : const sal_Bool bAssEnabled = pBtn != pImpl->pDeletePB && pImpl->pAssignPB->IsEnabled();
336 :
337 : // remove from the table
338 0 : sal_uInt16 nEvent = (sal_uInt16)(sal_uLong)pE->GetUserData();
339 0 : pThis->aTbl.Erase( nEvent );
340 :
341 0 : String sScriptURI;
342 0 : if( bAssEnabled )
343 : {
344 0 : sScriptURI = pImpl->pMacroLB->GetSelectedScriptURI();
345 0 : if( sScriptURI.CompareToAscii( "vnd.sun.star.script:", 20 ) == COMPARE_EQUAL )
346 : {
347 : pThis->aTbl.Insert(
348 0 : nEvent, SvxMacro( sScriptURI, rtl::OUString( SVX_MACRO_LANGUAGE_SF ) ) );
349 : }
350 : else
351 : {
352 : OSL_ENSURE( false, "_SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" );
353 : pThis->aTbl.Insert(
354 0 : nEvent, SvxMacro( sScriptURI, rtl::OUString( SVX_MACRO_LANGUAGE_STARBASIC ) ) );
355 : }
356 : }
357 :
358 0 : pImpl->pEventLB->SetUpdateMode( sal_False );
359 0 : pE->ReplaceItem( new SvLBoxString( pE, 0, sScriptURI ), LB_MACROS_ITEMPOS );
360 0 : rListBox.GetModel()->InvalidateEntry( pE );
361 0 : rListBox.Select( pE );
362 0 : rListBox.MakeVisible( pE );
363 0 : rListBox.SetUpdateMode( sal_True );
364 :
365 0 : pThis->EnableButtons();
366 0 : return 0;
367 : }
368 :
369 0 : IMPL_STATIC_LINK( _SfxMacroTabPage, TimeOut_Impl, Timer*, EMPTYARG )
370 : {
371 : // FillMacroList() can take a long time -> show wait cursor and disable input
372 0 : SfxTabDialog* pTabDlg = pThis->GetTabDialog();
373 : // perhaps the tabpage is part of a SingleTabDialog then pTabDlg == NULL
374 0 : if ( pTabDlg )
375 : {
376 0 : pTabDlg->EnterWait();
377 0 : pTabDlg->EnableInput( sal_False );
378 : }
379 0 : pThis->FillMacroList();
380 0 : if ( pTabDlg )
381 : {
382 0 : pTabDlg->EnableInput( sal_True );
383 0 : pTabDlg->LeaveWait();
384 : }
385 0 : return 0;
386 : }
387 :
388 0 : void _SfxMacroTabPage::InitAndSetHandler()
389 : {
390 0 : SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
391 0 : HeaderBar& rHeaderBar = mpImpl->pEventLB->GetHeaderBar();
392 0 : Link aLnk(STATIC_LINK(this, _SfxMacroTabPage, AssignDeleteHdl_Impl ));
393 0 : mpImpl->pMacroLB->SetDoubleClickHdl( aLnk );
394 0 : mpImpl->pDeletePB->SetClickHdl( aLnk );
395 0 : mpImpl->pAssignPB->SetClickHdl( aLnk );
396 0 : rListBox.SetDoubleClickHdl( aLnk );
397 :
398 0 : rListBox.SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectEvent_Impl ));
399 0 : mpImpl->pGroupLB->SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectGroup_Impl ));
400 0 : mpImpl->pMacroLB->SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectMacro_Impl ));
401 :
402 0 : rListBox.SetSelectionMode( SINGLE_SELECTION );
403 0 : rListBox.SetTabs( &nTabs[0], MAP_APPFONT );
404 0 : Size aSize( nTabs[ 2 ], 0 );
405 0 : rHeaderBar.InsertItem( ITEMID_EVENT, *mpImpl->pStrEvent, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() );
406 0 : aSize.Width() = 1764; // don't know what, so 42^2 is best to use...
407 0 : rHeaderBar.InsertItem( ITMEID_ASSMACRO, *mpImpl->pAssignedMacro, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() );
408 0 : rListBox.SetSpaceBetweenEntries( 0 );
409 :
410 0 : mpImpl->pEventLB->Show();
411 0 : mpImpl->pEventLB->ConnectElements();
412 :
413 0 : mpImpl->pEventLB->Enable( sal_True );
414 0 : mpImpl->pGroupLB->Enable( sal_True );
415 0 : mpImpl->pMacroLB->Enable( sal_True );
416 :
417 0 : mpImpl->pGroupLB->SetFunctionListBox( mpImpl->pMacroLB );
418 :
419 0 : }
420 :
421 0 : void _SfxMacroTabPage::FillMacroList()
422 : {
423 : mpImpl->pGroupLB->Init(
424 : ::com::sun::star::uno::Reference<
425 : ::com::sun::star::lang::XMultiServiceFactory >(),
426 : GetFrame(),
427 0 : ::rtl::OUString() );
428 0 : }
429 :
430 0 : void _SfxMacroTabPage::FillEvents()
431 : {
432 0 : SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
433 :
434 0 : sal_uLong nEntryCnt = rListBox.GetEntryCount();
435 :
436 : // get events from the table and fill the EventListBox respectively
437 0 : for( sal_uLong n = 0 ; n < nEntryCnt ; ++n )
438 : {
439 0 : SvTreeListEntry* pE = rListBox.GetEntry( n );
440 0 : if( pE )
441 : {
442 0 : SvLBoxString* pLItem = ( SvLBoxString* ) pE->GetItem( LB_MACROS_ITEMPOS );
443 : DBG_ASSERT( pLItem && SV_ITEM_ID_LBOXSTRING == pLItem->GetType(), "_SfxMacroTabPage::FillEvents(): no LBoxString" );
444 :
445 0 : String sOld( pLItem->GetText() );
446 0 : String sNew;
447 0 : sal_uInt16 nEventId = ( sal_uInt16 ) ( sal_uLong ) pE->GetUserData();
448 0 : if( aTbl.IsKeyValid( nEventId ) )
449 0 : sNew = ConvertToUIName_Impl( aTbl.Get( nEventId ) );
450 :
451 0 : if( sOld != sNew )
452 : {
453 0 : pE->ReplaceItem( new SvLBoxString( pE, 0, sNew ), LB_MACROS_ITEMPOS );
454 0 : rListBox.GetModel()->InvalidateEntry( pE );
455 0 : }
456 : }
457 : }
458 0 : }
459 :
460 0 : SfxMacroTabPage::SfxMacroTabPage( Window* pParent, const ResId& rResId, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet )
461 0 : : _SfxMacroTabPage( pParent, rResId, rSet )
462 : {
463 0 : mpImpl->pStrEvent = new String( CUI_RES( STR_EVENT ) );
464 0 : mpImpl->pAssignedMacro = new String( CUI_RES( STR_ASSMACRO ) );
465 0 : mpImpl->pEventLB = new _HeaderTabListBox( this, CUI_RES( LB_EVENT ) );
466 0 : mpImpl->pAssignPB = new PushButton( this, CUI_RES( PB_ASSIGN ) );
467 0 : mpImpl->pDeletePB = new PushButton( this, CUI_RES( PB_DELETE ) );
468 0 : mpImpl->pMacroFT = new FixedText( this, CUI_RES( FT_MACRO ) );
469 0 : mpImpl->pGroupLB = new SfxConfigGroupListBox_Impl( this, CUI_RES( LB_GROUP ) );
470 0 : mpImpl->pFT_MacroLBLabel = new FixedText( this, CUI_RES( FT_LABEL4LB_MACROS ) );
471 0 : mpImpl->maStaticMacroLBLabel= mpImpl->pFT_MacroLBLabel->GetText();
472 0 : mpImpl->pMacroLB = new SfxConfigFunctionListBox_Impl( this, CUI_RES( LB_MACROS ) );
473 0 : mpImpl->pMacroStr = new String( CUI_RES( STR_MACROS ) );
474 :
475 0 : FreeResource();
476 :
477 0 : SetFrame( rxDocumentFrame );
478 :
479 0 : InitAndSetHandler();
480 :
481 0 : ScriptChanged();
482 0 : }
483 :
484 0 : SfxTabPage* SfxMacroTabPage::Create( Window* pParent, const SfxItemSet& rAttrSet )
485 : {
486 0 : return new SfxMacroTabPage( pParent, CUI_RES( RID_SVXPAGE_EVENTASSIGN ), NULL, rAttrSet );
487 : }
488 :
489 0 : SfxMacroAssignDlg::SfxMacroAssignDlg( Window* pParent, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet )
490 0 : : SfxSingleTabDialog( pParent, rSet, 0 )
491 : {
492 0 : SfxTabPage* pPage = SfxMacroTabPage::Create( this, rSet );
493 0 : pPage->SetFrame( rxDocumentFrame );
494 0 : SetTabPage( pPage );
495 0 : }
496 :
497 0 : SfxMacroAssignDlg::~SfxMacroAssignDlg()
498 : {
499 3 : }
500 :
501 :
502 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|