Bump version to 4.3-4
[LibreOffice.git] / cui / source / tabpages / macroass.cxx
blobcc180d67f4ba3cf3f503cc889a53948fa553a0ad
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "macroass.hxx"
22 #include <basic/basmgr.hxx>
23 #include <comphelper/string.hxx>
24 #include <dialmgr.hxx>
25 #include <svl/macitem.hxx>
26 #include <svx/dialogs.hrc>
27 #include <svtools/svmedit.hxx>
28 #include "cfgutil.hxx"
29 #include <sfx2/app.hxx>
30 #include <sfx2/evntconf.hxx>
31 #include <sfx2/objsh.hxx>
32 #include "cuires.hrc"
33 #include <vcl/fixed.hxx>
34 #include "headertablistbox.hxx"
35 #include "svtools/svlbitm.hxx"
36 #include "svtools/treelistentry.hxx"
38 using ::com::sun::star::uno::Reference;
39 using ::com::sun::star::frame::XFrame;
41 class _SfxMacroTabPage_Impl
43 public:
44 _SfxMacroTabPage_Impl();
46 OUString maStaticMacroLBLabel;
47 PushButton* pAssignPB;
48 PushButton* pDeletePB;
49 OUString sStrEvent;
50 OUString sAssignedMacro;
51 MacroEventListBox* pEventLB;
52 VclFrame* pGroupFrame;
53 SfxConfigGroupListBox* pGroupLB;
54 VclFrame* pMacroFrame;
55 SfxConfigFunctionListBox* pMacroLB;
57 bool bReadOnly;
58 Timer maFillGroupTimer;
59 bool bGotEvents;
60 bool m_bDummyActivated; ///< has this tab page already been activated
63 _SfxMacroTabPage_Impl::_SfxMacroTabPage_Impl()
64 : pAssignPB(NULL)
65 , pDeletePB(NULL)
66 , pEventLB(NULL)
67 , pGroupFrame(NULL)
68 , pGroupLB(NULL)
69 , pMacroFrame(NULL)
70 , pMacroLB(NULL)
71 , bReadOnly(false)
72 , bGotEvents(false)
73 , m_bDummyActivated(false)
77 static sal_uInt16 aPageRg[] = {
78 SID_ATTR_MACROITEM, SID_ATTR_MACROITEM,
82 // attention, this array is indexed directly (0, 1, ...) in the code
83 static long nTabs[] =
85 2, // Number of Tabs
86 0, 90
89 // IDs for items in HeaderBar of EventLB
90 #define ITEMID_EVENT 1
91 #define ITMEID_ASSMACRO 2
94 #define LB_MACROS_ITEMPOS 2
96 OUString ConvertToUIName_Impl( SvxMacro *pMacro )
98 OUString aName( pMacro->GetMacName() );
99 OUString aEntry;
100 if ( pMacro->GetLanguage() != "JavaScript" )
102 sal_uInt16 nCount = comphelper::string::getTokenCount(aName, '.');
103 aEntry = aName.getToken( nCount-1, '.' );
104 if ( nCount > 2 )
106 aEntry += "(";
107 aEntry += aName.getToken( 0, '.' );
108 aEntry += ".";
109 aEntry += aName.getToken( nCount-2, '.' );
110 aEntry += ")";
112 return aEntry;
114 else
115 return aName;
118 void _SfxMacroTabPage::EnableButtons()
120 // don't do anything as long as the eventbox is empty
121 const SvTreeListEntry* pE = mpImpl->pEventLB->GetListBox().FirstSelected();
122 if ( pE )
124 // get bound macro
125 const SvxMacro* pM = aTbl.Get( (sal_uInt16)(sal_uLong) pE->GetUserData() );
126 mpImpl->pDeletePB->Enable( 0 != pM && !mpImpl->bReadOnly );
128 OUString sEventMacro;
129 sEventMacro = ((SvLBoxString*)pE->GetItem( LB_MACROS_ITEMPOS ))->GetText();
131 OUString sScriptURI = mpImpl->pMacroLB->GetSelectedScriptURI();
132 mpImpl->pAssignPB->Enable( !mpImpl->bReadOnly && !sScriptURI.equalsIgnoreAsciiCase( sEventMacro ) );
134 else
135 mpImpl->pAssignPB->Enable( false );
138 _SfxMacroTabPage::_SfxMacroTabPage(Window* pParent, const SfxItemSet& rAttrSet)
139 : SfxTabPage(pParent, "EventAssignPage", "cui/ui/eventassignpage.ui", rAttrSet)
141 mpImpl = new _SfxMacroTabPage_Impl;
144 _SfxMacroTabPage::~_SfxMacroTabPage()
146 DELETEZ( mpImpl );
149 void _SfxMacroTabPage::AddEvent( const OUString & rEventName, sal_uInt16 nEventId )
151 OUString sTmp( rEventName );
152 sTmp += "\t";
154 // if the table is valid already
155 SvxMacro* pM = aTbl.Get( nEventId );
156 if( pM )
158 OUString sNew( ConvertToUIName_Impl( pM ) );
159 sTmp += sNew;
162 SvTreeListEntry* pE = mpImpl->pEventLB->GetListBox().InsertEntry( sTmp );
163 pE->SetUserData( reinterpret_cast< void* >( sal::static_int_cast< sal_IntPtr >( nEventId )) );
166 void _SfxMacroTabPage::ScriptChanged()
168 // get new areas and their functions
169 mpImpl->pGroupFrame->Show();
170 mpImpl->pMacroFrame->Show();
172 EnableButtons();
175 bool _SfxMacroTabPage::FillItemSet( SfxItemSet& rSet )
177 SvxMacroItem aItem( GetWhich( aPageRg[0] ) );
178 ((SvxMacroTableDtor&)aItem.GetMacroTable()) = aTbl;
180 const SfxPoolItem* pItem;
181 if( SFX_ITEM_SET != GetItemSet().GetItemState( aItem.Which(), true, &pItem )
182 || aItem != *(SvxMacroItem*)pItem )
184 rSet.Put( aItem );
185 return true;
187 return false;
190 void _SfxMacroTabPage::LaunchFillGroup()
192 if (!mpImpl->maFillGroupTimer.GetTimeoutHdl().IsSet())
194 mpImpl->maFillGroupTimer.SetTimeoutHdl( STATIC_LINK( this, _SfxMacroTabPage, TimeOut_Impl ) );
195 mpImpl->maFillGroupTimer.SetTimeout( 0 );
196 mpImpl->maFillGroupTimer.Start();
200 void _SfxMacroTabPage::ActivatePage( const SfxItemSet& )
202 // fdo#57553 lazily init script providers, because it is annoying if done
203 // on dialog open (SfxTabDialog::Start_Impl activates all tab pages once!)
204 if (!mpImpl->m_bDummyActivated)
206 mpImpl->m_bDummyActivated = true;
207 return;
209 LaunchFillGroup();
212 void _SfxMacroTabPage::PageCreated(const SfxAllItemSet& aSet)
214 const SfxPoolItem* pEventsItem;
215 if( !mpImpl->bGotEvents && SFX_ITEM_SET == aSet.GetItemState( SID_EVENTCONFIG, true, &pEventsItem ) )
217 mpImpl->bGotEvents = true;
218 const SfxEventNamesList& rList = ((SfxEventNamesItem*)pEventsItem)->GetEvents();
219 for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
221 const SfxEventName *pOwn = rList.at(nNo);
222 AddEvent( pOwn->maUIName, pOwn->mnId );
227 void _SfxMacroTabPage::Reset( const SfxItemSet& rSet )
229 const SfxPoolItem* pItem;
230 if( SFX_ITEM_SET == rSet.GetItemState( GetWhich( aPageRg[0] ), true, &pItem ))
231 aTbl = ((SvxMacroItem*)pItem)->GetMacroTable();
233 const SfxPoolItem* pEventsItem;
234 if( !mpImpl->bGotEvents && SFX_ITEM_SET == rSet.GetItemState( SID_EVENTCONFIG, true, &pEventsItem ) )
236 mpImpl->bGotEvents = true;
237 const SfxEventNamesList& rList = ((SfxEventNamesItem*)pEventsItem)->GetEvents();
238 for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
240 const SfxEventName *pOwn = rList.at(nNo);
241 AddEvent( pOwn->maUIName, pOwn->mnId );
245 FillEvents();
247 SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
248 SvTreeListEntry* pE = rListBox.GetEntry( 0 );
249 if( pE )
250 rListBox.SetCurEntry( pE );
253 bool _SfxMacroTabPage::IsReadOnly() const
255 return mpImpl->bReadOnly;
258 IMPL_STATIC_LINK( _SfxMacroTabPage, SelectEvent_Impl, SvTabListBox*, EMPTYARG )
260 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
261 SvHeaderTabListBox& rListBox = pImpl->pEventLB->GetListBox();
262 SvTreeListEntry* pE = rListBox.FirstSelected();
263 sal_uLong nPos;
264 if( !pE || LISTBOX_ENTRY_NOTFOUND ==
265 ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) )
267 DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
268 return 0;
271 pThis->ScriptChanged();
272 pThis->EnableButtons();
273 return 0;
276 IMPL_STATIC_LINK( _SfxMacroTabPage, SelectGroup_Impl, ListBox*, EMPTYARG )
278 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
279 pImpl->pGroupLB->GroupSelected();
280 const OUString sScriptURI = pImpl->pMacroLB->GetSelectedScriptURI();
281 OUString aLabelText;
282 if( !sScriptURI.isEmpty() )
283 aLabelText = pImpl->maStaticMacroLBLabel;
284 pImpl->pMacroFrame->set_label( aLabelText );
286 pThis->EnableButtons();
287 return 0;
290 IMPL_STATIC_LINK( _SfxMacroTabPage, SelectMacro_Impl, ListBox*, EMPTYARG )
292 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
293 pImpl->pMacroLB->FunctionSelected();
294 pThis->EnableButtons();
295 return 0;
298 IMPL_STATIC_LINK( _SfxMacroTabPage, AssignDeleteHdl_Impl, PushButton*, pBtn )
300 _SfxMacroTabPage_Impl* pImpl = pThis->mpImpl;
301 SvHeaderTabListBox& rListBox = pImpl->pEventLB->GetListBox();
302 SvTreeListEntry* pE = rListBox.FirstSelected();
303 sal_uLong nPos;
304 if( !pE || LISTBOX_ENTRY_NOTFOUND ==
305 ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) )
307 DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
308 return 0;
311 const bool bAssEnabled = pBtn != pImpl->pDeletePB && pImpl->pAssignPB->IsEnabled();
313 // remove from the table
314 sal_uInt16 nEvent = (sal_uInt16)(sal_uLong)pE->GetUserData();
315 pThis->aTbl.Erase( nEvent );
317 OUString sScriptURI;
318 if( bAssEnabled )
320 sScriptURI = pImpl->pMacroLB->GetSelectedScriptURI();
321 if( sScriptURI.startsWith( "vnd.sun.star.script:" ) )
323 pThis->aTbl.Insert(
324 nEvent, SvxMacro( sScriptURI, OUString( SVX_MACRO_LANGUAGE_SF ) ) );
326 else
328 OSL_ENSURE( false, "_SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" );
329 pThis->aTbl.Insert(
330 nEvent, SvxMacro( sScriptURI, OUString( SVX_MACRO_LANGUAGE_STARBASIC ) ) );
334 pImpl->pEventLB->SetUpdateMode( false );
335 pE->ReplaceItem( new SvLBoxString( pE, 0, sScriptURI ), LB_MACROS_ITEMPOS );
336 rListBox.GetModel()->InvalidateEntry( pE );
337 rListBox.Select( pE );
338 rListBox.MakeVisible( pE );
339 rListBox.SetUpdateMode( true );
341 pThis->EnableButtons();
342 return 0;
345 IMPL_STATIC_LINK( _SfxMacroTabPage, TimeOut_Impl, Timer*, EMPTYARG )
347 // FillMacroList() can take a long time -> show wait cursor and disable input
348 SfxTabDialog* pTabDlg = pThis->GetTabDialog();
349 // perhaps the tabpage is part of a SingleTabDialog then pTabDlg == NULL
350 if ( pTabDlg )
352 pTabDlg->EnterWait();
353 pTabDlg->EnableInput( false );
355 pThis->FillMacroList();
356 if ( pTabDlg )
358 pTabDlg->EnableInput( true );
359 pTabDlg->LeaveWait();
361 return 0;
364 void _SfxMacroTabPage::InitAndSetHandler()
366 SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
367 HeaderBar& rHeaderBar = mpImpl->pEventLB->GetHeaderBar();
368 Link aLnk(STATIC_LINK(this, _SfxMacroTabPage, AssignDeleteHdl_Impl ));
369 mpImpl->pMacroLB->SetDoubleClickHdl( aLnk );
370 mpImpl->pDeletePB->SetClickHdl( aLnk );
371 mpImpl->pAssignPB->SetClickHdl( aLnk );
372 rListBox.SetDoubleClickHdl( aLnk );
374 rListBox.SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectEvent_Impl ));
375 mpImpl->pGroupLB->SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectGroup_Impl ));
376 mpImpl->pMacroLB->SetSelectHdl( STATIC_LINK( this, _SfxMacroTabPage, SelectMacro_Impl ));
378 rListBox.SetSelectionMode( SINGLE_SELECTION );
379 rListBox.SetTabs( &nTabs[0], MAP_APPFONT );
380 Size aSize( nTabs[ 2 ], 0 );
381 rHeaderBar.InsertItem( ITEMID_EVENT, mpImpl->sStrEvent, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() );
382 aSize.Width() = 1764; // don't know what, so 42^2 is best to use...
383 rHeaderBar.InsertItem( ITMEID_ASSMACRO, mpImpl->sAssignedMacro, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() );
384 rListBox.SetSpaceBetweenEntries( 0 );
386 mpImpl->pEventLB->Show();
387 mpImpl->pEventLB->ConnectElements();
389 mpImpl->pEventLB->Enable( true );
390 mpImpl->pGroupLB->Enable( true );
391 mpImpl->pMacroLB->Enable( true );
393 mpImpl->pGroupLB->SetFunctionListBox( mpImpl->pMacroLB );
397 void _SfxMacroTabPage::FillMacroList()
399 mpImpl->pGroupLB->Init(
400 ::com::sun::star::uno::Reference<
401 ::com::sun::star::uno::XComponentContext >(),
402 GetFrame(),
403 OUString(), false);
406 void _SfxMacroTabPage::FillEvents()
408 SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
410 sal_uLong nEntryCnt = rListBox.GetEntryCount();
412 // get events from the table and fill the EventListBox respectively
413 for( sal_uLong n = 0 ; n < nEntryCnt ; ++n )
415 SvTreeListEntry* pE = rListBox.GetEntry( n );
416 if( pE )
418 SvLBoxString* pLItem = ( SvLBoxString* ) pE->GetItem( LB_MACROS_ITEMPOS );
419 DBG_ASSERT( pLItem && SV_ITEM_ID_LBOXSTRING == pLItem->GetType(), "_SfxMacroTabPage::FillEvents(): no LBoxString" );
421 OUString sOld( pLItem->GetText() );
422 OUString sNew;
423 sal_uInt16 nEventId = ( sal_uInt16 ) ( sal_uLong ) pE->GetUserData();
424 if( aTbl.IsKeyValid( nEventId ) )
425 sNew = ConvertToUIName_Impl( aTbl.Get( nEventId ) );
427 if( sOld != sNew )
429 pE->ReplaceItem( new SvLBoxString( pE, 0, sNew ), LB_MACROS_ITEMPOS );
430 rListBox.GetModel()->InvalidateEntry( pE );
436 SfxMacroTabPage::SfxMacroTabPage(Window* pParent, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet )
437 : _SfxMacroTabPage( pParent, rSet )
439 mpImpl->sStrEvent = get<FixedText>("eventft")->GetText();
440 mpImpl->sAssignedMacro = get<FixedText>("assignft")->GetText();
441 get(mpImpl->pEventLB , "assignments");
442 get(mpImpl->pAssignPB, "assign");
443 get(mpImpl->pDeletePB, "delete");
444 get(mpImpl->pGroupFrame, "groupframe");
445 get(mpImpl->pGroupLB, "libraries");
446 get(mpImpl->pMacroFrame, "macroframe");
447 mpImpl->maStaticMacroLBLabel = mpImpl->pMacroFrame->get_label();
448 get(mpImpl->pMacroLB, "macros");
450 SetFrame( rxDocumentFrame );
452 InitAndSetHandler();
454 ScriptChanged();
457 namespace
459 SfxMacroTabPage* CreateSfxMacroTabPage( Window* pParent, const SfxItemSet& rAttrSet )
461 return new SfxMacroTabPage( pParent, NULL, rAttrSet );
465 SfxTabPage* SfxMacroTabPage::Create( Window* pParent, const SfxItemSet& rAttrSet )
467 return CreateSfxMacroTabPage(pParent, rAttrSet);
470 SfxMacroAssignDlg::SfxMacroAssignDlg(Window* pParent,
471 const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet)
472 : SfxSingleTabDialog(pParent, rSet, "EventAssignDialog",
473 "cui/ui/eventassigndialog.ui")
475 SfxMacroTabPage* pPage = CreateSfxMacroTabPage(get_content_area(), rSet);
476 pPage->SetFrame( rxDocumentFrame );
477 SetTabPage( pPage );
478 pPage->LaunchFillGroup();
481 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */