xref: /aoo42x/main/cui/source/customize/macropg.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 #include <basic/basmgr.hxx>
27 
28 #include "macropg.hxx"
29 #include <vcl/msgbox.hxx>
30 #define _SVSTDARR_STRINGSDTOR
31 #include <svl/svstdarr.hxx>
32 #include <svtools/svmedit.hxx>
33 #include <svl/eitem.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <sfx2/app.hxx>
36 #include <sfx2/objsh.hxx>
37 #include <sfx2/sfxdefs.hxx>
38 #include <com/sun/star/container/NoSuchElementException.hpp>
39 #include <com/sun/star/lang/IllegalArgumentException.hpp>
40 #include <dialmgr.hxx>
41 #include "selector.hxx"
42 #include "cfg.hxx"
43 #include "macropg.hrc"
44 #include "helpid.hrc"
45 #include <cuires.hrc>
46 #include "headertablistbox.hxx"
47 #include "macropg_impl.hxx"
48 #include <svx/dialogs.hrc> // RID_SVXPAGE_MACROASSIGN
49 #include <comphelper/namedvaluecollection.hxx>
50 
51 #include <algorithm>
52 #include <set>
53 
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::uno;
56 
57 static ::rtl::OUString aVndSunStarUNO =
58 	::rtl::OUString::createFromAscii( "vnd.sun.star.UNO:" );
59 static ::rtl::OUString aVndSunStarScript =
60 	::rtl::OUString::createFromAscii( "vnd.sun.star.script:" );
61 
62 _SvxMacroTabPage_Impl::_SvxMacroTabPage_Impl( const SfxItemSet& rAttrSet ) :
63 	pAssignFT( NULL ),
64     pAssignPB( NULL ),
65 	pAssignComponentPB( NULL ),
66     pDeletePB( NULL ),
67 	pMacroImg( NULL ),
68 	pComponentImg( NULL ),
69 	pMacroImg_h( NULL ),
70 	pComponentImg_h( NULL ),
71     pStrEvent( NULL ),
72     pAssignedMacro( NULL ),
73     pEventLB( NULL ),
74     bReadOnly( sal_False ),
75 	bIDEDialogMode( sal_False )
76 {
77 	const SfxPoolItem* pItem;
78 	if ( SFX_ITEM_SET == rAttrSet.GetItemState( SID_ATTR_MACROITEM, sal_False, &pItem ) )
79         bIDEDialogMode = ((const SfxBoolItem*)pItem)->GetValue();
80 }
81 
82 _SvxMacroTabPage_Impl::~_SvxMacroTabPage_Impl()
83 {
84 	delete pAssignFT;
85     delete pAssignPB;
86 	delete pAssignComponentPB;
87     delete pDeletePB;
88 	delete pMacroImg;
89 	delete pComponentImg;
90 	delete pMacroImg_h;
91 	delete pComponentImg_h;
92     delete pStrEvent;
93     delete pAssignedMacro;
94     delete pEventLB;
95 }
96 
97 // Achtung im Code wird dieses Array direkt (0, 1, ...) indiziert
98 static long nTabs[] =
99     {
100         2, // Number of Tabs
101         0, 90
102     };
103 
104 #define TAB_WIDTH_MIN        10
105 
106 // IDs for items in HeaderBar of EventLB
107 #define    ITEMID_EVENT        1
108 #define    ITMEID_ASSMACRO        2
109 
110 
111 #define LB_EVENTS_ITEMPOS    1
112 #define LB_MACROS_ITEMPOS    2
113 
114 
115 IMPL_LINK( _HeaderTabListBox, HeaderEndDrag_Impl, HeaderBar*, pBar )
116 {
117     DBG_ASSERT( pBar == &maHeaderBar, "*_HeaderTabListBox::HeaderEndDrag_Impl: something is wrong here..." );
118 	(void)pBar;
119 
120     if( !maHeaderBar.GetCurItemId() )
121         return 0;
122 
123     if( !maHeaderBar.IsItemMode() )
124     {
125         Size    aSz;
126         sal_uInt16    _nTabs = maHeaderBar.GetItemCount();
127         long    nTmpSz = 0;
128         long    nWidth = maHeaderBar.GetItemSize( ITEMID_EVENT );
129         long    nBarWidth = maHeaderBar.GetSizePixel().Width();
130 
131         if( nWidth < TAB_WIDTH_MIN )
132             maHeaderBar.SetItemSize( ITEMID_EVENT, TAB_WIDTH_MIN );
133         else if( ( nBarWidth - nWidth ) < TAB_WIDTH_MIN )
134             maHeaderBar.SetItemSize( ITEMID_EVENT, nBarWidth - TAB_WIDTH_MIN );
135 
136         {
137             long    _nWidth;
138             for( sal_uInt16 i = 1 ; i < _nTabs ; ++i )
139             {
140                 _nWidth = maHeaderBar.GetItemSize( i );
141                 aSz.Width() =  _nWidth + nTmpSz;
142                 nTmpSz += _nWidth;
143                 maListBox.SetTab( i, PixelToLogic( aSz, MapMode( MAP_APPFONT ) ).Width(), MAP_APPFONT );
144             }
145         }
146     }
147     return 1;
148 }
149 
150 long _HeaderTabListBox::Notify( NotifyEvent& rNEvt )
151 {
152     long    nRet = Control::Notify( rNEvt );
153 
154     if( rNEvt.GetType() == EVENT_GETFOCUS )
155 	{
156 		if ( rNEvt.GetWindow() != &maListBox )
157 			maListBox.GrabFocus();
158 	}
159 
160     return nRet;
161 }
162 
163 _HeaderTabListBox::_HeaderTabListBox( Window* pParent, const ResId& rId ) :
164     Control( pParent, rId ),
165     maListBox( this, WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP ),
166     maHeaderBar( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER )
167 {
168     maListBox.SetHelpId( HID_MACRO_HEADERTABLISTBOX );
169 }
170 
171 _HeaderTabListBox::~_HeaderTabListBox()
172 {
173 }
174 
175 void _HeaderTabListBox::ConnectElements( void )
176 {
177     // calc pos and size of header bar
178     Point    aPnt( 0, 0 );
179     Size    aSize( maHeaderBar.CalcWindowSizePixel() );
180     Size    aCtrlSize( GetOutputSizePixel() );
181     aSize.Width() = aCtrlSize.Width();
182     maHeaderBar.SetPosSizePixel( aPnt, aSize );
183 
184     // calc pos and size of ListBox
185     aPnt.Y() += aSize.Height();
186     aSize.Height() = aCtrlSize.Height() - aSize.Height();
187     maListBox.SetPosSizePixel( aPnt, aSize );
188 
189     // set handler
190     maHeaderBar.SetEndDragHdl( LINK( this, _HeaderTabListBox, HeaderEndDrag_Impl ) );
191 
192     maListBox.InitHeaderBar( &maHeaderBar );
193 }
194 
195 void _HeaderTabListBox::Show( sal_Bool bVisible, sal_uInt16 nFlags )
196 {
197     maListBox.Show( bVisible, nFlags );
198     maHeaderBar.Show( bVisible, nFlags );
199 }
200 
201 void _HeaderTabListBox::Enable( bool bEnable, bool bChild )
202 {
203     maListBox.Enable( bEnable, bChild );
204     maHeaderBar.Enable( bEnable, bChild );
205 }
206 
207 // assign button ("Add Command") is enabled only if it is not read only
208 // delete button ("Remove Command") is enabled if a current binding exists
209 //     and it is not read only
210 void _SvxMacroTabPage::EnableButtons()
211 {
212     const SvLBoxEntry* pE = mpImpl->pEventLB->GetListBox().FirstSelected();
213     if ( pE )
214     {
215         SvLBoxString* pEventMacro = (SvLBoxString*)pE->GetItem( LB_MACROS_ITEMPOS );
216         mpImpl->pDeletePB->Enable( 0 != pEventMacro && !mpImpl->bReadOnly );
217 
218         mpImpl->pAssignPB->Enable( !mpImpl->bReadOnly );
219 		if( mpImpl->pAssignComponentPB )
220 			mpImpl->pAssignComponentPB->Enable( !mpImpl->bReadOnly );
221     }
222 }
223 
224 _SvxMacroTabPage::_SvxMacroTabPage( Window* pParent, const ResId& rResId, const SfxItemSet& rAttrSet )
225     : SfxTabPage( pParent, rResId, rAttrSet ),
226     m_xAppEvents(0),
227     m_xDocEvents(0),
228     bReadOnly(false),
229     bDocModified(false),
230     bAppEvents(false),
231     bInitialized(false)
232 {
233     mpImpl = new _SvxMacroTabPage_Impl( rAttrSet );
234 }
235 
236 _SvxMacroTabPage::~_SvxMacroTabPage()
237 {
238     // need to delete the user data
239     SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
240     SvLBoxEntry* pE = rListBox.GetEntry( 0 );
241     while( pE )
242     {
243         ::rtl::OUString* pEventName = (::rtl::OUString*)pE->GetUserData();
244         delete pEventName;
245         pE->SetUserData((void*)0);
246         pE = rListBox.NextSibling( pE );
247     }
248     DELETEZ( mpImpl );
249 }
250 // -----------------------------------------------------------------------------
251 void _SvxMacroTabPage::InitResources()
252 {
253     // Note: the order here controls the order in which the events are displayed in the UI!
254 
255     // the event name to UI string mappings for App Events
256     aDisplayNames.push_back( EventDisplayName( "OnStartApp",            RID_SVXSTR_EVENT_STARTAPP ) );
257     aDisplayNames.push_back( EventDisplayName( "OnCloseApp",            RID_SVXSTR_EVENT_CLOSEAPP ) );
258     aDisplayNames.push_back( EventDisplayName( "OnCreate",              RID_SVXSTR_EVENT_CREATEDOC ) );
259     aDisplayNames.push_back( EventDisplayName( "OnNew",                 RID_SVXSTR_EVENT_NEWDOC ) );
260     aDisplayNames.push_back( EventDisplayName( "OnLoadFinished",        RID_SVXSTR_EVENT_LOADDOCFINISHED ) );
261     aDisplayNames.push_back( EventDisplayName( "OnLoad",                RID_SVXSTR_EVENT_OPENDOC ) );
262     aDisplayNames.push_back( EventDisplayName( "OnPrepareUnload",       RID_SVXSTR_EVENT_PREPARECLOSEDOC ) );
263     aDisplayNames.push_back( EventDisplayName( "OnUnload",              RID_SVXSTR_EVENT_CLOSEDOC ) ) ;
264     aDisplayNames.push_back( EventDisplayName( "OnViewCreated",         RID_SVXSTR_EVENT_VIEWCREATED ) );
265 	aDisplayNames.push_back( EventDisplayName( "OnPrepareViewClosing",  RID_SVXSTR_EVENT_PREPARECLOSEVIEW ) );
266     aDisplayNames.push_back( EventDisplayName( "OnViewClosed",          RID_SVXSTR_EVENT_CLOSEVIEW ) ) ;
267     aDisplayNames.push_back( EventDisplayName( "OnFocus",               RID_SVXSTR_EVENT_ACTIVATEDOC ) );
268     aDisplayNames.push_back( EventDisplayName( "OnUnfocus",             RID_SVXSTR_EVENT_DEACTIVATEDOC ) );
269     aDisplayNames.push_back( EventDisplayName( "OnSave",                RID_SVXSTR_EVENT_SAVEDOC ) );
270     aDisplayNames.push_back( EventDisplayName( "OnSaveDone",            RID_SVXSTR_EVENT_SAVEDOCDONE ) );
271     aDisplayNames.push_back( EventDisplayName( "OnSaveFailed",          RID_SVXSTR_EVENT_SAVEDOCFAILED ) );
272     aDisplayNames.push_back( EventDisplayName( "OnSaveAs",              RID_SVXSTR_EVENT_SAVEASDOC ) );
273     aDisplayNames.push_back( EventDisplayName( "OnSaveAsDone",          RID_SVXSTR_EVENT_SAVEASDOCDONE ) );
274     aDisplayNames.push_back( EventDisplayName( "OnSaveAsFailed",        RID_SVXSTR_EVENT_SAVEASDOCFAILED ) );
275     aDisplayNames.push_back( EventDisplayName( "OnCopyTo",              RID_SVXSTR_EVENT_COPYTODOC ) );
276     aDisplayNames.push_back( EventDisplayName( "OnCopyToDone",          RID_SVXSTR_EVENT_COPYTODOCDONE ) );
277     aDisplayNames.push_back( EventDisplayName( "OnCopyToFailed",        RID_SVXSTR_EVENT_COPYTODOCFAILED ) );
278     aDisplayNames.push_back( EventDisplayName( "OnPrint",               RID_SVXSTR_EVENT_PRINTDOC ) );
279     aDisplayNames.push_back( EventDisplayName( "OnModifyChanged",       RID_SVXSTR_EVENT_MODIFYCHANGED ) );
280     aDisplayNames.push_back( EventDisplayName( "OnTitleChanged",        RID_SVXSTR_EVENT_TITLECHANGED ) );
281 //    aDisplayNames.push_back( EventDisplayName( "OnModeChanged",         RID_SVXSTR_EVENT_MODECHANGED ) );
282 //    aDisplayNames.push_back( EventDisplayName( "OnVisAreaChanged",      RID_SVXSTR_EVENT_VISAREACHANGED ) );
283 //    aDisplayNames.push_back( EventDisplayName( "OnStorageChanged",      RID_SVXSTR_EVENT_STORAGECHANGED ) );
284 
285 	// application specific events
286     aDisplayNames.push_back( EventDisplayName( "OnMailMerge",           RID_SVXSTR_EVENT_MAILMERGE ) );
287     aDisplayNames.push_back( EventDisplayName( "OnMailMergeFinished",           RID_SVXSTR_EVENT_MAILMERGE_END ) );
288     aDisplayNames.push_back( EventDisplayName( "OnFieldMerge",           RID_SVXSTR_EVENT_FIELDMERGE ) );
289     aDisplayNames.push_back( EventDisplayName( "OnFieldMergeFinished",           RID_SVXSTR_EVENT_FIELDMERGE_FINISHED ) );
290     aDisplayNames.push_back( EventDisplayName( "OnPageCountChange",     RID_SVXSTR_EVENT_PAGECOUNTCHANGE ) );
291     aDisplayNames.push_back( EventDisplayName( "OnSubComponentOpened",  RID_SVXSTR_EVENT_SUBCOMPONENT_OPENED ) );
292     aDisplayNames.push_back( EventDisplayName( "OnSubComponentClosed",  RID_SVXSTR_EVENT_SUBCOMPONENT_CLOSED ) );
293 //    aDisplayNames.push_back( EventDisplayName( "OnLayoutFinished",		RID_SVXSTR_EVENT_LAYOUT_FINISHED ) );
294     aDisplayNames.push_back( EventDisplayName( "OnSelect",              RID_SVXSTR_EVENT_SELECTIONCHANGED ) );
295     aDisplayNames.push_back( EventDisplayName( "OnDoubleClick",         RID_SVXSTR_EVENT_DOUBLECLICK ) );
296     aDisplayNames.push_back( EventDisplayName( "OnRightClick",          RID_SVXSTR_EVENT_RIGHTCLICK ) );
297     aDisplayNames.push_back( EventDisplayName( "OnCalculate",           RID_SVXSTR_EVENT_CALCULATE ) );
298     aDisplayNames.push_back( EventDisplayName( "OnChange",              RID_SVXSTR_EVENT_CONTENTCHANGED ) );
299 
300     // the event name to UI string mappings for forms & dialogs
301     //
302     aDisplayNames.push_back( EventDisplayName( "approveAction",         RID_SVXSTR_EVENT_APPROVEACTIONPERFORMED ) );
303     aDisplayNames.push_back( EventDisplayName( "actionPerformed",       RID_SVXSTR_EVENT_ACTIONPERFORMED ) );
304     aDisplayNames.push_back( EventDisplayName( "changed",               RID_SVXSTR_EVENT_CHANGED ) );
305     aDisplayNames.push_back( EventDisplayName( "textChanged",           RID_SVXSTR_EVENT_TEXTCHANGED ) );
306     aDisplayNames.push_back( EventDisplayName( "itemStateChanged",      RID_SVXSTR_EVENT_ITEMSTATECHANGED ) );
307     aDisplayNames.push_back( EventDisplayName( "focusGained",           RID_SVXSTR_EVENT_FOCUSGAINED ) );
308     aDisplayNames.push_back( EventDisplayName( "focusLost",             RID_SVXSTR_EVENT_FOCUSLOST ) );
309     aDisplayNames.push_back( EventDisplayName( "keyPressed",            RID_SVXSTR_EVENT_KEYTYPED ) );
310     aDisplayNames.push_back( EventDisplayName( "keyReleased",           RID_SVXSTR_EVENT_KEYUP ) );
311     aDisplayNames.push_back( EventDisplayName( "mouseEntered",          RID_SVXSTR_EVENT_MOUSEENTERED ) );
312     aDisplayNames.push_back( EventDisplayName( "mouseDragged",          RID_SVXSTR_EVENT_MOUSEDRAGGED ) );
313     aDisplayNames.push_back( EventDisplayName( "mouseMoved",            RID_SVXSTR_EVENT_MOUSEMOVED ) );
314     aDisplayNames.push_back( EventDisplayName( "mousePressed",          RID_SVXSTR_EVENT_MOUSEPRESSED ) );
315     aDisplayNames.push_back( EventDisplayName( "mouseReleased",         RID_SVXSTR_EVENT_MOUSERELEASED ) );
316     aDisplayNames.push_back( EventDisplayName( "mouseExited",           RID_SVXSTR_EVENT_MOUSEEXITED ) );
317     aDisplayNames.push_back( EventDisplayName( "approveReset",          RID_SVXSTR_EVENT_APPROVERESETTED ) );
318     aDisplayNames.push_back( EventDisplayName( "resetted",              RID_SVXSTR_EVENT_RESETTED ) );
319     aDisplayNames.push_back( EventDisplayName( "approveSubmit",         RID_SVXSTR_EVENT_SUBMITTED ) );
320     aDisplayNames.push_back( EventDisplayName( "approveUpdate",         RID_SVXSTR_EVENT_BEFOREUPDATE ) );
321     aDisplayNames.push_back( EventDisplayName( "updated",               RID_SVXSTR_EVENT_AFTERUPDATE ) );
322     aDisplayNames.push_back( EventDisplayName( "loaded",                RID_SVXSTR_EVENT_LOADED ) );
323     aDisplayNames.push_back( EventDisplayName( "reloading",             RID_SVXSTR_EVENT_RELOADING ) );
324     aDisplayNames.push_back( EventDisplayName( "reloaded",              RID_SVXSTR_EVENT_RELOADED ) );
325     aDisplayNames.push_back( EventDisplayName( "unloading",             RID_SVXSTR_EVENT_UNLOADING ) );
326     aDisplayNames.push_back( EventDisplayName( "unloaded",              RID_SVXSTR_EVENT_UNLOADED ) );
327     aDisplayNames.push_back( EventDisplayName( "confirmDelete",         RID_SVXSTR_EVENT_CONFIRMDELETE ) );
328     aDisplayNames.push_back( EventDisplayName( "approveRowChange",      RID_SVXSTR_EVENT_APPROVEROWCHANGE ) );
329     aDisplayNames.push_back( EventDisplayName( "rowChanged",            RID_SVXSTR_EVENT_ROWCHANGE ) );
330     aDisplayNames.push_back( EventDisplayName( "approveCursorMove",     RID_SVXSTR_EVENT_POSITIONING ) );
331     aDisplayNames.push_back( EventDisplayName( "cursorMoved",           RID_SVXSTR_EVENT_POSITIONED ) );
332     aDisplayNames.push_back( EventDisplayName( "approveParameter",      RID_SVXSTR_EVENT_APPROVEPARAMETER ) );
333     aDisplayNames.push_back( EventDisplayName( "errorOccured",          RID_SVXSTR_EVENT_ERROROCCURED ) );
334     aDisplayNames.push_back( EventDisplayName( "adjustmentValueChanged",   RID_SVXSTR_EVENT_ADJUSTMENTVALUECHANGED ) );
335 }
336 
337 // the following method is called when the user clicks OK
338 // We use the contents of the hashes to replace the settings
339 sal_Bool _SvxMacroTabPage::FillItemSet( SfxItemSet& /*rSet*/ )
340 {
341     try
342     {
343         ::rtl::OUString eventName;
344         if( m_xAppEvents.is() )
345         {
346             EventsHash::iterator h_itEnd =  m_appEventsHash.end();
347             EventsHash::iterator h_it = m_appEventsHash.begin();
348             for ( ; h_it !=  h_itEnd; ++h_it )
349             {
350                 eventName = h_it->first;
351                 try
352                 {
353                     m_xAppEvents->replaceByName( eventName, GetPropsByName( eventName, m_appEventsHash ) );
354                 }
355                 catch( const Exception& )
356                 {
357                 	DBG_UNHANDLED_EXCEPTION();
358                 }
359             }
360         }
361         if( m_xDocEvents.is() && bDocModified )
362         {
363             EventsHash::iterator h_itEnd =  m_docEventsHash.end();
364             EventsHash::iterator h_it = m_docEventsHash.begin();
365             for ( ; h_it !=  h_itEnd; ++h_it )
366             {
367                 eventName = h_it->first;
368                 try
369                 {
370                     m_xDocEvents->replaceByName( eventName, GetPropsByName( eventName, m_docEventsHash ) );
371                 }
372                 catch( const Exception& )
373                 {
374                 	DBG_UNHANDLED_EXCEPTION();
375                 }
376             }
377             // if we have a valid XModifiable (in the case of doc events)
378             // call setModified(true)
379             // in principle this should not be necessary (see issue ??)
380             if(m_xModifiable.is())
381             {
382                 m_xModifiable->setModified( sal_True );
383             }
384         }
385     }
386     catch(Exception&)
387     {
388     }
389     // what is the return value about??
390     return sal_False;
391 }
392 
393 // the following method clears the bindings in the hashes for both doc & app
394 void _SvxMacroTabPage::Reset()
395 {
396     // called once in creation - don't reset the data this time
397     if(!bInitialized)
398     {
399         bInitialized = true;
400         return;
401     }
402 
403     try
404     {
405 			::rtl::OUString sEmpty;
406             if( m_xAppEvents.is() )
407             {
408                 EventsHash::iterator h_itEnd =  m_appEventsHash.end();
409                 EventsHash::iterator h_it = m_appEventsHash.begin();
410                 for ( ; h_it !=  h_itEnd; ++h_it )
411                 {
412                     h_it->second.second = sEmpty;
413                 }
414             }
415             if( m_xDocEvents.is() && bDocModified )
416             {
417                 EventsHash::iterator h_itEnd =  m_docEventsHash.end();
418                 EventsHash::iterator h_it = m_docEventsHash.begin();
419                 for ( ; h_it !=  h_itEnd; ++h_it )
420                 {
421                     h_it->second.second = sEmpty;
422                 }
423                 // if we have a valid XModifiable (in the case of doc events)
424                 // call setModified(true)
425                 if(m_xModifiable.is())
426                 {
427                     m_xModifiable->setModified( sal_True );
428                 }
429             }
430     }
431     catch(Exception&)
432     {
433     }
434     DisplayAppEvents(bAppEvents);
435 }
436 
437 void _SvxMacroTabPage::SetReadOnly( sal_Bool bSet )
438 {
439     mpImpl->bReadOnly = bSet;
440 }
441 
442 sal_Bool _SvxMacroTabPage::IsReadOnly() const
443 {
444     return mpImpl->bReadOnly;
445 }
446 
447 
448 class IconLBoxString : public SvLBoxString
449 {
450 	Image* m_pMacroImg;
451 	Image* m_pComponentImg;
452 	Image* m_pMacroImg_h;
453 	Image* m_pComponentImg_h;
454 	int m_nxImageOffset;
455 
456     public:
457         IconLBoxString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const String& sText,
458 			Image* pMacroImg, Image* pComponentImg,
459 			Image* pMacroImg_h, Image* pComponentImg_h );
460         virtual void Paint(const Point& aPos, SvLBox& aDevice, sal_uInt16 nFlags, SvLBoxEntry* pEntry );
461 };
462 
463 
464 IconLBoxString::IconLBoxString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const String& sText,
465 	Image* pMacroImg, Image* pComponentImg, Image* pMacroImg_h, Image* pComponentImg_h )
466 		: SvLBoxString( pEntry, nFlags, sText )
467 		, m_pMacroImg( pMacroImg )
468 		, m_pComponentImg( pComponentImg )
469 		, m_pMacroImg_h( pMacroImg_h )
470 		, m_pComponentImg_h( pComponentImg_h )
471 {
472 	m_nxImageOffset = 20;
473 }
474 
475 //===============================================
476 void IconLBoxString::Paint( const Point& aPos, SvLBox& aDevice,
477 							   sal_uInt16 /*nFlags*/, SvLBoxEntry* /*pEntry*/ )
478 {
479 	String aTxt( GetText() );
480 	if( aTxt.Len() )
481 	{
482 		::rtl::OUString aURL( aTxt );
483 		sal_Int32 nIndex = aURL.indexOf( aVndSunStarUNO );
484 		bool bUNO = nIndex == 0;
485 
486 		sal_Bool bHC = aDevice.GetSettings().GetStyleSettings().GetHighContrastMode();
487 		const Image* pImg;
488 		if( bHC )
489 			pImg = bUNO ? m_pComponentImg_h : m_pMacroImg_h;
490 		else
491 			pImg = bUNO ? m_pComponentImg : m_pMacroImg;
492 		aDevice.DrawImage( aPos, *pImg );
493 
494 		::rtl::OUString aPureMethod;
495 		if( bUNO )
496 		{
497 			sal_Int32 nBegin = aVndSunStarUNO.getLength();
498 			aPureMethod = aURL.copy( nBegin );
499 		}
500 		else
501 		{
502 			sal_Int32 nBegin = aVndSunStarScript.getLength();
503 			aPureMethod = aURL.copy( nBegin );
504 			aPureMethod = aPureMethod.copy( 0, aPureMethod.indexOf( '?' ) );
505 		}
506 
507 		Point aPnt(aPos);
508 		aPnt.X() += m_nxImageOffset;
509 		aDevice.DrawText( aPnt, aPureMethod );
510 	}
511 }
512 
513 
514 // displays the app events if appEvents=true, otherwise displays the doc events
515 void _SvxMacroTabPage::DisplayAppEvents( bool appEvents)
516 {
517     bAppEvents = appEvents;
518 
519     SvHeaderTabListBox&        rListBox = mpImpl->pEventLB->GetListBox();
520     mpImpl->pEventLB->SetUpdateMode( sal_False );
521     rListBox.Clear();
522     SvLBoxEntry*    pE = rListBox.GetEntry( 0 );
523     EventsHash* eventsHash;
524     Reference< container::XNameReplace> nameReplace;
525     if(bAppEvents)
526     {
527         eventsHash = &m_appEventsHash;
528         nameReplace = m_xAppEvents;
529     }
530     else
531     {
532         eventsHash = &m_docEventsHash;
533         nameReplace = m_xDocEvents;
534     }
535     // have to use the original XNameReplace since the hash iterators do
536     // not guarantee the order in which the elements are returned
537     if(!nameReplace.is())
538     {
539         return;
540     }
541 
542     Sequence< ::rtl::OUString > eventNames = nameReplace->getElementNames();
543     ::std::set< ::rtl::OUString > aEventNamesCache;
544     ::std::copy(
545         eventNames.getConstArray(),
546         eventNames.getConstArray() + eventNames.getLength(),
547         ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aEventNamesCache, aEventNamesCache.end() )
548     );
549 
550     for (   EventDisplayNames::const_iterator displayableEvent = aDisplayNames.begin();
551             displayableEvent != aDisplayNames.end();
552             ++displayableEvent
553         )
554     {
555         ::rtl::OUString sEventName( ::rtl::OUString::createFromAscii( displayableEvent->pAsciiEventName ) );
556         if ( !nameReplace->hasByName( sEventName ) )
557             continue;
558 
559         EventsHash::iterator h_it = eventsHash->find( sEventName );
560         if( h_it == eventsHash->end() )
561         {
562             OSL_ENSURE( false, "_SvxMacroTabPage::DisplayAppEvents: something's suspicious here!" );
563             continue;
564         }
565 
566         ::rtl::OUString eventURL = h_it->second.second;
567         String displayName( CUI_RES( displayableEvent->nEventResourceID ) );
568 
569         displayName += '\t';
570         SvLBoxEntry*    _pE = rListBox.InsertEntry( displayName );
571         ::rtl::OUString* pEventName = new ::rtl::OUString( sEventName );
572         _pE->SetUserData( (void*)pEventName );
573         String sNew( eventURL );
574         _pE->ReplaceItem( new IconLBoxString( _pE, 0, sNew,
575 			mpImpl->pMacroImg, mpImpl->pComponentImg,
576 			mpImpl->pMacroImg_h, mpImpl->pComponentImg_h ), LB_MACROS_ITEMPOS );
577         rListBox.GetModel()->InvalidateEntry( _pE );
578         rListBox.Select( _pE );
579         rListBox.MakeVisible( _pE );
580     }
581 
582 	pE = rListBox.GetEntry(0);
583     if( pE )
584 	{
585         rListBox.Select( pE );
586         rListBox.MakeVisible( pE );
587 	}
588 
589     rListBox.SetUpdateMode( sal_True );
590     EnableButtons();
591 }
592 
593 // select event handler on the listbox
594 IMPL_STATIC_LINK( _SvxMacroTabPage, SelectEvent_Impl, SvTabListBox*, EMPTYARG )
595 {
596     _SvxMacroTabPage_Impl*    pImpl = pThis->mpImpl;
597     SvHeaderTabListBox&        rListBox = pImpl->pEventLB->GetListBox();
598     SvLBoxEntry*            pE = rListBox.FirstSelected();
599     sal_uLong                    nPos;
600 
601     if( !pE || LISTBOX_ENTRY_NOTFOUND ==
602         ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) )
603     {
604         DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
605         return 0;
606     }
607 
608     pThis->EnableButtons();
609     return 0;
610 }
611 
612 IMPL_STATIC_LINK( _SvxMacroTabPage, AssignDeleteHdl_Impl, PushButton*, pBtn )
613 {
614 	return GenericHandler_Impl( pThis, pBtn );
615 }
616 
617 IMPL_STATIC_LINK( _SvxMacroTabPage, DoubleClickHdl_Impl, SvTabListBox *, EMPTYARG )
618 {
619 	return GenericHandler_Impl( pThis, NULL );
620 }
621 
622 // handler for double click on the listbox, and for the assign/delete buttons
623 long _SvxMacroTabPage::GenericHandler_Impl( _SvxMacroTabPage* pThis, PushButton* pBtn )
624 {
625     _SvxMacroTabPage_Impl*    pImpl = pThis->mpImpl;
626     SvHeaderTabListBox& rListBox = pImpl->pEventLB->GetListBox();
627     SvLBoxEntry* pE = rListBox.FirstSelected();
628     sal_uLong nPos;
629     if( !pE || LISTBOX_ENTRY_NOTFOUND ==
630         ( nPos = rListBox.GetModel()->GetAbsPos( pE ) ) )
631     {
632         DBG_ASSERT( pE, "wo kommt der leere Eintrag her?" );
633         return 0;
634     }
635 
636     const sal_Bool bAssEnabled = pBtn != pImpl->pDeletePB && pImpl->pAssignPB->IsEnabled();
637 
638     ::rtl::OUString* pEventName = (::rtl::OUString*)pE->GetUserData();
639 
640     ::rtl::OUString sEventURL;
641     ::rtl::OUString sEventType;
642     if(pThis->bAppEvents)
643     {
644         EventsHash::iterator h_it = pThis->m_appEventsHash.find( *pEventName );
645         if(h_it != pThis->m_appEventsHash.end() )
646         {
647             sEventType = h_it->second.first;
648             sEventURL = h_it->second.second;
649         }
650     }
651     else
652     {
653         EventsHash::iterator h_it = pThis->m_docEventsHash.find( *pEventName );
654         if(h_it != pThis->m_docEventsHash.end() )
655         {
656             sEventType = h_it->second.first;
657             sEventURL = h_it->second.second;
658         }
659     }
660 
661 	bool bDoubleClick = (pBtn == NULL);
662 	bool bUNOAssigned = (sEventURL.indexOf( aVndSunStarUNO ) == 0);
663     if( pBtn == pImpl->pDeletePB )
664     {
665         // delete pressed
666         sEventType = ::rtl::OUString::createFromAscii("Script");
667         sEventURL = ::rtl::OUString();
668         if(!pThis->bAppEvents)
669 			pThis->bDocModified = true;
670     }
671     else if (   (   ( pBtn != NULL )
672                 &&  ( pBtn == pImpl->pAssignComponentPB )
673                 )
674             ||  (   bDoubleClick
675                 &&  bUNOAssigned
676                 )
677             )
678     {
679 		AssignComponentDialog* pAssignDlg = new AssignComponentDialog( pThis, sEventURL );
680 
681         short ret = pAssignDlg->Execute();
682         if( ret )
683 		{
684 	        sEventType = ::rtl::OUString::createFromAscii("UNO");
685 	        sEventURL = pAssignDlg->getURL();
686             if(!pThis->bAppEvents)
687 				pThis->bDocModified = true;
688 		}
689 		delete pAssignDlg;
690 	}
691     else if( bAssEnabled )
692     {
693         // assign pressed
694         SvxScriptSelectorDialog* pDlg = new SvxScriptSelectorDialog( pThis, sal_False, pThis->GetFrame() );
695         if( pDlg )
696         {
697             short ret = pDlg->Execute();
698             if ( ret )
699             {
700                 sEventType = ::rtl::OUString::createFromAscii("Script");
701                 sEventURL = pDlg->GetScriptURL();
702                 if(!pThis->bAppEvents)
703 					pThis->bDocModified = true;
704             }
705         }
706     }
707 
708     // update the hashes
709     if(pThis->bAppEvents)
710     {
711         EventsHash::iterator h_it = pThis->m_appEventsHash.find( *pEventName );
712         h_it->second.first = sEventType;
713         h_it->second.second = sEventURL;
714     }
715     else
716     {
717         EventsHash::iterator h_it = pThis->m_docEventsHash.find( *pEventName );
718         h_it->second.first = sEventType;
719         h_it->second.second = sEventURL;
720     }
721 
722     // update the listbox entry
723     pImpl->pEventLB->SetUpdateMode( sal_False );
724     // pE->ReplaceItem( new SvLBoxString( pE, 0, sEventURL ), LB_MACROS_ITEMPOS );
725     pE->ReplaceItem( new IconLBoxString( pE, 0, sEventURL,
726 			pImpl->pMacroImg, pImpl->pComponentImg,
727 			pImpl->pMacroImg_h, pImpl->pComponentImg_h ), LB_MACROS_ITEMPOS );
728 
729     rListBox.GetModel()->InvalidateEntry( pE );
730     rListBox.Select( pE );
731     rListBox.MakeVisible( pE );
732     rListBox.SetUpdateMode( sal_True );
733 
734     pThis->EnableButtons();
735     return 0;
736 }
737 
738 // pass in the XNameReplace.
739 // can remove the 3rd arg once issue ?? is fixed
740 void _SvxMacroTabPage::InitAndSetHandler( Reference< container::XNameReplace> xAppEvents, Reference< container::XNameReplace> xDocEvents, Reference< util::XModifiable > xModifiable )
741 {
742     m_xAppEvents = xAppEvents;
743     m_xDocEvents = xDocEvents;
744     m_xModifiable = xModifiable;
745     SvHeaderTabListBox&    rListBox = mpImpl->pEventLB->GetListBox();
746     HeaderBar&            rHeaderBar = mpImpl->pEventLB->GetHeaderBar();
747     Link                aLnk(STATIC_LINK(this, _SvxMacroTabPage, AssignDeleteHdl_Impl ));
748     mpImpl->pDeletePB->SetClickHdl(    aLnk );
749     mpImpl->pAssignPB->SetClickHdl(    aLnk );
750 	if( mpImpl->pAssignComponentPB )
751 	    mpImpl->pAssignComponentPB->SetClickHdl( aLnk );
752     rListBox.SetDoubleClickHdl( STATIC_LINK(this, _SvxMacroTabPage, DoubleClickHdl_Impl ) );
753 
754     rListBox.SetSelectHdl( STATIC_LINK( this, _SvxMacroTabPage, SelectEvent_Impl ));
755 
756     rListBox.SetSelectionMode( SINGLE_SELECTION );
757     rListBox.SetTabs( &nTabs[0], MAP_APPFONT );
758     Size aSize( nTabs[ 2 ], 0 );
759     rHeaderBar.InsertItem( ITEMID_EVENT, *mpImpl->pStrEvent, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() );
760     aSize.Width() = 1764;        // don't know what, so 42^2 is best to use...
761     rHeaderBar.InsertItem( ITMEID_ASSMACRO, *mpImpl->pAssignedMacro, LogicToPixel( aSize, MapMode( MAP_APPFONT ) ).Width() );
762     rListBox.SetSpaceBetweenEntries( 0 );
763 
764     mpImpl->pEventLB->Show();
765     mpImpl->pEventLB->ConnectElements();
766 
767 	long nMinLineHeight = mpImpl->pMacroImg->GetSizePixel().Height() + 2;
768 	if( nMinLineHeight > mpImpl->pEventLB->GetListBox().GetEntryHeight() )
769 	    mpImpl->pEventLB->GetListBox().SetEntryHeight(
770             sal::static_int_cast< short >(nMinLineHeight) );
771 
772     mpImpl->pEventLB->Enable( sal_True );
773 
774     if(!m_xAppEvents.is())
775     {
776         return;
777     }
778     Sequence< ::rtl::OUString > eventNames = m_xAppEvents->getElementNames();
779     sal_Int32 nEventCount = eventNames.getLength();
780     for(sal_Int32 nEvent = 0; nEvent < nEventCount; ++nEvent )
781     {
782         //need exception handling here
783         try
784         {
785             m_appEventsHash[ eventNames[nEvent] ] = GetPairFromAny( m_xAppEvents->getByName( eventNames[nEvent] ) );
786         }
787         catch (Exception e)
788         {}
789     }
790     if(m_xDocEvents.is())
791     {
792         eventNames = m_xDocEvents->getElementNames();
793         nEventCount = eventNames.getLength();
794         for(sal_Int32 nEvent = 0; nEvent < nEventCount; ++nEvent )
795         {
796             try
797             {
798                 m_docEventsHash[ eventNames[nEvent] ] = GetPairFromAny( m_xDocEvents->getByName( eventNames[nEvent] ) );
799             }
800             catch (Exception e)
801             {}
802         }
803     }
804 }
805 
806 // returns the two props EventType & Script for a given event name
807 Any _SvxMacroTabPage::GetPropsByName( const ::rtl::OUString& eventName, EventsHash& eventsHash )
808 {
809     const ::std::pair< ::rtl::OUString, ::rtl::OUString >& rAssignedEvent( eventsHash[ eventName ] );
810 
811     Any aReturn;
812     ::comphelper::NamedValueCollection aProps;
813     if ( rAssignedEvent.first.getLength() && rAssignedEvent.second.getLength() )
814     {
815         aProps.put( "EventType", rAssignedEvent.first );
816         aProps.put( "Script", rAssignedEvent.second );
817     }
818     aReturn <<= aProps.getPropertyValues();
819 
820     return aReturn;
821 }
822 
823 // converts the Any returned by GetByName into a pair which can be stored in
824 // the EventHash
825 ::std::pair< ::rtl::OUString, ::rtl::OUString  > _SvxMacroTabPage::GetPairFromAny( Any aAny )
826 {
827     Sequence< beans::PropertyValue > props;
828     ::rtl::OUString type, url;
829     if( sal_True == ( aAny >>= props ) )
830     {
831         ::comphelper::NamedValueCollection aProps( props );
832         type = aProps.getOrDefault( "EventType", type );
833         url = aProps.getOrDefault( "Script", url );
834     }
835     return ::std::make_pair( type, url );
836 }
837 
838 SvxMacroTabPage::SvxMacroTabPage( Window* pParent, const Reference< frame::XFrame >& _rxDocumentFrame, const SfxItemSet& rSet, Reference< container::XNameReplace > xNameReplace, sal_uInt16 nSelectedIndex )
839     : _SvxMacroTabPage( pParent, CUI_RES( RID_SVXPAGE_MACROASSIGN ), rSet )
840 {
841     mpImpl->pStrEvent           = new String(						CUI_RES( STR_EVENT ) );
842     mpImpl->pAssignedMacro      = new String(						CUI_RES( STR_ASSMACRO ) );
843     mpImpl->pEventLB            = new _HeaderTabListBox( this,		CUI_RES( LB_EVENT ) );
844     mpImpl->pAssignFT			= new FixedText( this,				CUI_RES( FT_ASSIGN ) );
845     mpImpl->pAssignPB           = new PushButton( this,				CUI_RES( PB_ASSIGN ) );
846     mpImpl->pDeletePB           = new PushButton( this,				CUI_RES( PB_DELETE ) );
847 	mpImpl->pAssignComponentPB  = new PushButton( this,			CUI_RES( PB_ASSIGN_COMPONENT ) );
848 	mpImpl->pMacroImg			= new Image(						CUI_RES(IMG_MACRO) );
849 	mpImpl->pComponentImg		= new Image(						CUI_RES(IMG_COMPONENT) );
850 	mpImpl->pMacroImg_h			= new Image(						CUI_RES(IMG_MACRO_H) );
851 	mpImpl->pComponentImg_h		= new Image(						CUI_RES(IMG_COMPONENT_H) );
852 
853     FreeResource();
854 
855     SetFrame( _rxDocumentFrame );
856 
857 	if( !mpImpl->bIDEDialogMode )
858 	{
859 		// Size aSizeAssign;
860 		// Point aPosAssign;
861 		// mpImpl->pAssignPB->GetPosSizePixel( aPosAssign, aSizeAssign );
862 		Point aPosAssign = mpImpl->pAssignPB->GetPosPixel();
863 		Point aPosComp = mpImpl->pAssignComponentPB->GetPosPixel();
864 
865 		Point aPosDelete = mpImpl->pDeletePB->GetPosPixel();
866 		long nYDiff = aPosComp.Y() - aPosAssign.Y();
867 		aPosDelete.Y() -= nYDiff;
868 		mpImpl->pDeletePB->SetPosPixel( aPosDelete );
869 
870 		mpImpl->pAssignComponentPB->Hide();
871 		mpImpl->pAssignComponentPB->Disable();
872 	}
873 
874     // must be done after FreeResource is called
875 	InitResources();
876 
877     mpImpl->pEventLB->GetListBox().SetHelpId( HID_SVX_MACRO_LB_EVENT );
878 
879     InitAndSetHandler( xNameReplace, Reference< container::XNameReplace>(0), Reference< util::XModifiable >(0));
880     DisplayAppEvents(true);
881     SvHeaderTabListBox& rListBox = mpImpl->pEventLB->GetListBox();
882     SvLBoxEntry* pE = rListBox.GetEntry( (sal_uLong)nSelectedIndex );
883     if( pE )
884         rListBox.Select(pE);
885 }
886 
887 SvxMacroTabPage::~SvxMacroTabPage()
888 {
889 }
890 
891 SvxMacroAssignDlg::SvxMacroAssignDlg( Window* pParent, const Reference< frame::XFrame >& _rxDocumentFrame, const SfxItemSet& rSet,
892 	const Reference< container::XNameReplace >& xNameReplace, sal_uInt16 nSelectedIndex )
893 		: SvxMacroAssignSingleTabDialog( pParent, rSet, 0 )
894 {
895     SetTabPage( new SvxMacroTabPage( this, _rxDocumentFrame, rSet, xNameReplace, nSelectedIndex ) );
896 }
897 
898 SvxMacroAssignDlg::~SvxMacroAssignDlg()
899 {
900 }
901 
902 
903 //===============================================
904 
905 IMPL_LINK(AssignComponentDialog, ButtonHandler, Button *, EMPTYARG)
906 {
907 	::rtl::OUString aMethodName = maMethodEdit.GetText();
908 	maURL = ::rtl::OUString();
909 	if( aMethodName.getLength() )
910 	{
911 		maURL = aVndSunStarUNO;
912 		maURL += aMethodName;
913 	}
914 	EndDialog(1);
915     return 0;
916 }
917 
918 AssignComponentDialog::AssignComponentDialog( Window * pParent, const ::rtl::OUString& rURL )
919 	: ModalDialog( pParent, CUI_RES( RID_SVXDLG_ASSIGNCOMPONENT ) )
920 	, maMethodLabel( this, CUI_RES( FT_METHOD ) )
921 	, maMethodEdit( this, CUI_RES( EDIT_METHOD ) )
922 	, maOKButton( this, CUI_RES( RID_PB_OK ) )
923 	, maCancelButton( this, CUI_RES( RID_PB_CANCEL ) )
924 	, maHelpButton( this, CUI_RES( RID_PB_HELP ) )
925 	, maURL( rURL )
926 {
927 	FreeResource();
928 	maOKButton.SetClickHdl(LINK(this, AssignComponentDialog, ButtonHandler));
929 
930 	::rtl::OUString aMethodName;
931 	if( maURL.getLength() )
932 	{
933 		sal_Int32 nIndex = maURL.indexOf( aVndSunStarUNO );
934 		if( nIndex == 0 )
935 		{
936 			sal_Int32 nBegin = aVndSunStarUNO.getLength();
937 			aMethodName = maURL.copy( nBegin );
938 		}
939 	}
940 	maMethodEdit.SetText( aMethodName, Selection( 0, SELECTION_MAX ) );
941 }
942 
943 AssignComponentDialog::~AssignComponentDialog()
944 {
945 }
946 
947 // -----------------------------------------------------------------------
948 
949 IMPL_LINK( SvxMacroAssignSingleTabDialog, OKHdl_Impl, Button *, pButton )
950 {
951     (void)pButton; //unused
952 	pPage->FillItemSet( *pOutSet );
953 	EndDialog( RET_OK );
954 	return 0;
955 }
956 
957 // -----------------------------------------------------------------------
958 
959 SvxMacroAssignSingleTabDialog::SvxMacroAssignSingleTabDialog
960 	( Window *pParent, const SfxItemSet& rSet, sal_uInt16 nUniqueId ) :
961 		SfxModalDialog( pParent, nUniqueId, WinBits( WB_STDMODAL | WB_3DLOOK ) ),
962 		pFixedLine      ( 0 ),
963 		pOKBtn          ( 0 ),
964 		pCancelBtn      ( 0 ),
965 		pHelpBtn        ( 0 ),
966 		pPage           ( 0 ),
967 		pOptions        ( &rSet ),
968 		pOutSet         ( 0 )
969 {}
970 
971 
972 // -----------------------------------------------------------------------
973 
974 SvxMacroAssignSingleTabDialog::~SvxMacroAssignSingleTabDialog()
975 {
976 	delete pFixedLine;
977 	delete pOKBtn;
978 	delete pCancelBtn;
979 	delete pHelpBtn;
980 	delete pPage;
981 }
982 
983 // -----------------------------------------------------------------------
984 
985 // According to SfxSingleTabDialog
986 void SvxMacroAssignSingleTabDialog::SetTabPage( SfxTabPage* pTabPage )
987 {
988 	pFixedLine = new FixedLine( this );
989 
990 	pOKBtn = new OKButton( this, WB_DEFBUTTON );
991 	pOKBtn->SetClickHdl( LINK( this, SvxMacroAssignSingleTabDialog, OKHdl_Impl ) );
992 
993 	pCancelBtn = new CancelButton( this );
994 	pHelpBtn = new HelpButton( this );
995 
996 	pPage = pTabPage;
997 
998 	if ( pPage )
999 	{
1000 		String sUserData;
1001 		pPage->SetUserData( sUserData );
1002 		pPage->Reset( *pOptions );
1003 		pPage->Show();
1004 
1005 		// Set dialog's and buttons' size and position according to tabpage size
1006 		long nSpaceX = LogicToPixel( Size( 6, 0 ), MAP_APPFONT ).Width();
1007 		long nSpaceY = LogicToPixel( Size( 0, 6 ), MAP_APPFONT ).Height();
1008 		long nHalfSpaceX = LogicToPixel( Size( 3, 0 ), MAP_APPFONT ).Width();
1009 		long nHalfSpaceY = LogicToPixel( Size( 0, 3 ), MAP_APPFONT ).Height();
1010 
1011 		pPage->SetPosPixel( Point() );
1012 		Size aTabpageSize( pPage->GetSizePixel() );
1013 		Size aDialogSize( aTabpageSize );
1014 		Size aButtonSize = LogicToPixel( Size( 50, 14 ), MAP_APPFONT );
1015 		long nButtonWidth  = aButtonSize.Width();
1016 		long nButtonHeight = aButtonSize.Height();
1017 
1018 		Size aFixedLineSize( aTabpageSize );
1019 		long nFixedLineHeight = LogicToPixel( Size( 0, 8 ), MAP_APPFONT ).Height();
1020 		aFixedLineSize.Height() = nFixedLineHeight;
1021 
1022 		aDialogSize.Height() += nFixedLineHeight + nButtonHeight + nSpaceY + nHalfSpaceY;
1023 		SetOutputSizePixel( aDialogSize );
1024 
1025 		long nButtonPosY = aTabpageSize.Height() + nFixedLineHeight + nHalfSpaceY;
1026 		long nHelpButtonPosX = nSpaceX;
1027 		pHelpBtn->SetPosSizePixel( Point( nHelpButtonPosX, nButtonPosY), aButtonSize );
1028 		pHelpBtn->Show();
1029 
1030 		long nCancelButtonPosX = aDialogSize.Width() - nButtonWidth - nSpaceX + 1;
1031 		pCancelBtn->SetPosSizePixel( Point( nCancelButtonPosX, nButtonPosY), aButtonSize );
1032 		pCancelBtn->Show();
1033 
1034 		long nOkButtonPosX = nCancelButtonPosX - nButtonWidth - nHalfSpaceX;
1035 		pOKBtn->SetPosSizePixel( Point( nOkButtonPosX, nButtonPosY), aButtonSize );
1036 		pOKBtn->Show();
1037 
1038 		long nFixedLinePosY = aTabpageSize.Height();
1039 		pFixedLine->SetPosSizePixel( Point( 0, nFixedLinePosY), aFixedLineSize );
1040 		pFixedLine->Show();
1041 
1042 		// Get text from TabPage
1043 		SetText( pPage->GetText() );
1044 
1045 		// Get IDs from TabPage
1046 		SetHelpId( pPage->GetHelpId() );
1047 		SetUniqueId( pPage->GetUniqueId() );
1048 	}
1049 }
1050