xref: /trunk/main/automation/source/server/recorder.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_automation.hxx"
30 #include <osl/mutex.hxx>
31 
32 #include <vcl/window.hxx>
33 #include <vcl/vclevent.hxx>
34 #include <vcl/button.hxx>
35 #include <vcl/edit.hxx>
36 #include <vcl/spinfld.hxx>
37 #include <vcl/msgbox.hxx>
38 #include <vcl/toolbox.hxx>
39 #include <vcl/lstbox.hxx>
40 #include <vcl/sound.hxx>
41 #include <vcl/combobox.hxx>
42 #include <vcl/floatwin.hxx>
43 #include <basic/ttstrhlp.hxx>
44 #include "statemnt.hxx"
45 #include "retstrm.hxx"
46 #include "rcontrol.hxx"
47 #include "recorder.hxx"
48 
49 #include <comphelper/uieventslogger.hxx>
50 
51 MacroRecorder* MacroRecorder::pMacroRecorder = NULL;
52 
53 MacroRecorder::MacroRecorder()
54 : pLastWin( NULL )
55 , pEditModify( NULL )
56 , pActionParent( NULL )
57 , aKeyUniqueID()
58 , pKeyWin( NULL )
59 , bKeyFollowFocus( sal_False )
60 , m_bRecord( sal_False )
61 , m_bLog( sal_False )
62 {
63     aHookRefresh.SetTimeout( 500 );
64     aHookRefresh.SetTimeoutHdl( LINK( this, MacroRecorder, HookRefreshHdl) );
65     aHookRefresh.Start();
66     aEventListenerHdl = LINK( this, MacroRecorder, EventListener );
67     AddEventHooks();
68 }
69 
70 MacroRecorder::~MacroRecorder()
71 {
72     aHookRefresh.Stop();
73     RemoveEventHooks();
74 }
75 
76 void MacroRecorder::AddEventHooks()
77 {
78     Window *pTopLevel = Application::GetFirstTopLevelWindow();
79     while ( pTopLevel )
80     {
81         Window *pParent = pTopLevel;
82         while ( pParent->GetParent() )
83             pParent = pParent->GetParent();
84 
85         pParent->RemoveChildEventListener( aEventListenerHdl );     // might be instrumented already
86         pParent->AddChildEventListener( aEventListenerHdl );
87 
88         pTopLevel = Application::GetNextTopLevelWindow( pTopLevel );
89     }
90 }
91 
92 void MacroRecorder::RemoveEventHooks()
93 {
94     Window *pTopLevel = Application::GetFirstTopLevelWindow();
95     while ( pTopLevel )
96     {
97         pTopLevel->RemoveChildEventListener( aEventListenerHdl );
98         pTopLevel = Application::GetNextTopLevelWindow( pTopLevel );
99     }
100 }
101 
102 IMPL_LINK( MacroRecorder, HookRefreshHdl, void*, EMPTYARG )
103 {
104     AddEventHooks();
105     return 0;
106 }
107 
108 void MacroRecorder::LogVCL( rtl::OString aParentID, sal_uInt16 nVCLWindowType, rtl::OString aID, String aMethod, sal_uInt16 nParam )
109 {
110     ::comphelper::UiEventsLogger::logVcl( Id2Str( aParentID ), nVCLWindowType, Id2Str( aID ), aMethod, nParam );
111 }
112 
113 void MacroRecorder::LogVCL( rtl::OString aParentID, sal_uInt16 nVCLWindowType, rtl::OString aID, String aMethod )
114 {
115     ::comphelper::UiEventsLogger::logVcl( Id2Str( aParentID ), nVCLWindowType, Id2Str( aID ), aMethod );
116 }
117 
118 Window* MacroRecorder::GetParentWithID( Window* pThis )
119 {
120     Window *pOverlap = pThis->GetWindow( WINDOW_OVERLAP );
121     while ( pOverlap != pThis && !pThis->GetUniqueOrHelpId().getLength() && pThis->GET_REAL_PARENT() )
122         pThis = pThis->GET_REAL_PARENT();
123     return pThis;
124 }
125 
126 rtl::OString MacroRecorder::GetParentID( Window* pThis )
127 {
128     if ( pThis->GetParent() )
129         return pThis->GetParent()->GetUniqueOrHelpId();
130     else
131         return rtl::OString();
132 }
133 
134 IMPL_LINK( MacroRecorder, EventListener, VclSimpleEvent*, pEvent )
135 {
136     sal_Bool bSendData = sal_False;
137 
138     if ( pEvent->ISA( VclWindowEvent ) )
139     {
140         VclWindowEvent* pWinEvent = ( VclWindowEvent* ) pEvent;
141         Window* pWin = pWinEvent->GetWindow();
142         sal_uLong nEventID = pWinEvent->GetId();
143 #if OSL_DEBUG_LEVEL > 1
144         if ( nEventID >= 1001 && nEventID != VCLEVENT_WINDOW_KEYUP )
145             nEventID = pWinEvent->GetId();  // Just something to set a breakpoint
146         else
147             return 0;
148 #endif
149 
150 // check for different action after collecting keys
151         // send if there_is_something_to_send
152         // and eather event_is_not_of_interest
153         //     or ( new_window and new_window_is_interesting )    ( ignore interesting events to uninteresting window )
154 
155         if (  aKeyString.Len()
156             && (  ( nEventID != VCLEVENT_WINDOW_KEYINPUT
157                  && nEventID != VCLEVENT_WINDOW_MOUSEMOVE
158                  && nEventID != VCLEVENT_WINDOW_COMMAND
159                  && nEventID != VCLEVENT_WINDOW_KEYUP )
160                 || ( pKeyWin != pWin
161                     && ( pWin->GetType() == WINDOW_CONTROL || pWin->GetType() == WINDOW_WINDOW )
162                    )
163                )
164            )
165         {
166             if ( m_bRecord )
167             {
168                 // we cannot access pKeyWin since it might have dissapeared
169                 if ( bKeyFollowFocus )
170                     StatementList::pRet->GenReturn( RET_MacroRecorder, aKeyUniqueID, (sal_uInt16)M_TypeKeys, aKeyString, bKeyFollowFocus );
171                 else
172                     StatementList::pRet->GenReturn( RET_MacroRecorder, aKeyUniqueID, (sal_uInt16)M_TypeKeys, aKeyString );
173 #if OSL_DEBUG_LEVEL > 1
174                 StatementList::pRet->GenReturn( RET_MacroRecorder, aKeyUniqueID, (sal_uInt16)M_TypeKeys, String::CreateFromInt32( nEventID ) );
175 #endif
176                 bSendData = sal_True;
177             }
178             if ( m_bLog )
179             {
180 //  HACK Too many KeyEvents generated              LogVCL( rtl::OString(), 0, aKeyUniqueID, CUniString("TypeKeys"), aKeyString.Len() );
181             }
182             // cleanup
183             aKeyString.Erase();
184             pKeyWin = NULL;
185             bKeyFollowFocus = sal_False;
186         }
187 
188         switch ( pWin->GetType() )
189         {
190             case WINDOW_TABPAGE:
191                 switch( nEventID )
192                 {
193                     case VCLEVENT_WINDOW_ACTIVATE:
194                         if ( m_bRecord )
195                         {
196                             StatementList::pRet->GenReturn( RET_MacroRecorder, rtl::OString(), (comm_USHORT)(M_SetPage|M_RET_NUM_CONTROL), Id2Str( pWin->GetUniqueOrHelpId() ) );
197                             bSendData = sal_True;
198                         }
199                         if ( m_bLog )
200                         {
201                             LogVCL( rtl::OString(), pWin->GetType(), pWin->GetUniqueOrHelpId(), CUniString("SetPage") );
202                         }
203                         break;
204                 }
205                 break;
206             case WINDOW_RADIOBUTTON:
207             case WINDOW_IMAGERADIOBUTTON:
208                 switch( nEventID )
209                 {
210                     case VCLEVENT_BUTTON_CLICK:  // VCLEVENT_RADIOBUTTON_TOGGLE
211                         {
212                             if ( ((RadioButton*)pWin)->IsChecked() )
213                             {
214                                 if ( m_bRecord )
215                                 {
216                                     StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), (comm_USHORT)M_Check );
217                                     bSendData = sal_True;
218                                 }
219                                 if ( m_bLog )
220                                 {
221                                     LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), CUniString("Check") );
222                                 }
223                             }
224                         }
225                         break;
226                 }
227                 break;
228             case WINDOW_CHECKBOX:
229             case WINDOW_TRISTATEBOX:
230                 switch( nEventID )
231                 {
232                     case VCLEVENT_BUTTON_CLICK: //VCLEVENT_CHECKBOX_TOGGLE:
233                         {
234                             comm_USHORT nMethod;
235                             String aMethod;
236                             switch ( ((TriStateBox*)pWin)->GetState() )
237                             {
238                                 case STATE_CHECK: nMethod = M_Check; aMethod = CUniString("Check"); break;
239                                 case STATE_NOCHECK: nMethod = M_UnCheck; aMethod = CUniString("UnCheck"); break;
240                                 case STATE_DONTKNOW: nMethod = M_TriState; aMethod = CUniString("TriState"); break;
241                                 default: nMethod = M_Check;
242                                     DBG_ERROR( "Unknown state in TriStateBox::GetState()" );
243                             }
244                             if ( m_bRecord )
245                             {
246                                 StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), nMethod );
247                                 bSendData = sal_True;
248                             }
249                             if ( m_bLog )
250                             {
251                                 LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), aMethod );
252                             }
253                         }
254                         break;
255                 }
256                 break;
257             case WINDOW_EDIT:
258             case WINDOW_MULTILINEEDIT:
259                 switch( nEventID )
260                 {
261                     case VCLEVENT_EDIT_MODIFY:
262                         pEditModify = pWin;
263                         aEditModifyString = ((Edit*)pWin)->GetText();
264                         break;
265                 }
266                 break;
267             case WINDOW_MULTILISTBOX:
268                 switch( nEventID )
269                 {
270                     case VCLEVENT_LISTBOX_SELECT:
271                         Sound::Beep();
272                 }
273             case WINDOW_LISTBOX:
274                 switch( nEventID )
275                 {
276 //                    case VCLEVENT_LISTBOX_DOUBLECLICK:
277                     case VCLEVENT_LISTBOX_SELECT:
278                         if ( m_bRecord )
279                         {
280                             StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), (comm_USHORT)M_Select, comm_ULONG( ((ListBox*)pWin)->GetSelectEntryPos() +1 ) );
281                             bSendData = sal_True;
282                         }
283                         if ( m_bLog )
284                         {
285                             LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), CUniString("Select"), ((ListBox*)pWin)->GetSelectEntryPos() );
286                         }
287                         break;
288                 }
289                 break;
290             case WINDOW_COMBOBOX:
291             case WINDOW_PATTERNBOX:
292             case WINDOW_NUMERICBOX:
293             case WINDOW_METRICBOX:
294             case WINDOW_CURRENCYBOX:
295             case WINDOW_DATEBOX:
296             case WINDOW_TIMEBOX:
297                 switch( nEventID )
298                 {
299                     case VCLEVENT_EDIT_MODIFY:
300                         pEditModify = pWin;
301                         aEditModifyString = ((Edit*)pWin)->GetText();
302                         break;
303                     case VCLEVENT_COMBOBOX_SELECT:
304                         {
305                             pEditModify = NULL;
306                             aEditModifyString.Erase();
307 
308                             sal_uInt16 nPos = ((ComboBox*)pWin)->GetEntryPos(((ComboBox*)pWin)->GetText());
309                             if ( m_bRecord )
310                             {
311                                 if ( nPos == COMBOBOX_ENTRY_NOTFOUND )
312                                     Sound::Beep();
313                                 else
314                                 {
315                                     StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), (comm_USHORT)M_Select, (comm_ULONG) nPos+1 );
316                                     bSendData = sal_True;
317                                 }
318                             }
319                             if ( m_bLog )
320                             {
321                                 LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), CUniString("Select"), nPos );
322                             }
323                         }
324                 }
325                 break;
326             case WINDOW_PUSHBUTTON:
327             case WINDOW_OKBUTTON:
328             case WINDOW_CANCELBUTTON:
329             case WINDOW_IMAGEBUTTON:
330             case WINDOW_MOREBUTTON:
331             case WINDOW_HELPBUTTON:
332                 switch( nEventID )
333                 {
334                     case VCLEVENT_BUTTON_CLICK:
335                         Window* pParent = pWin->GetParent();
336                         sal_Bool bDone = sal_False;
337                         if ( pParent->IsDialog() && !pWin->GetUniqueOrHelpId().getLength() )
338                         {
339                             switch ( pParent->GetType() )
340                             {
341                                 case WINDOW_MESSBOX:
342                                 case WINDOW_INFOBOX:
343                                 case WINDOW_WARNINGBOX:
344                                 case WINDOW_ERRORBOX:
345                                 case WINDOW_QUERYBOX:
346                                 case WINDOW_BUTTONDIALOG:
347                                     {
348                                         comm_USHORT nMethod;
349                                         String aMethod;
350                                         ButtonDialog* pBD = (ButtonDialog*)pParent;
351 
352                                         // we have to find the current Button ID ourselves since it is not generated at this point :-(
353                                         sal_uInt16 nCurrentButtonId = 0xffff;    // Some wild value to wak up people
354                                         sal_uInt16 i;
355                                         for ( i = 0; i < pBD->GetButtonCount() ; i++ )
356                                         {
357                                             if ( pBD->GetPushButton( pBD->GetButtonId(i) ) == pWin )
358                                             {
359                                                 nCurrentButtonId = pBD->GetButtonId(i);
360                                                 break;
361                                             }
362                                         }
363 
364                                         switch ( nCurrentButtonId )
365                                         {
366                                             case BUTTONID_OK: nMethod = M_OK; aMethod = CUniString("OK"); break;
367                                             case BUTTONID_CANCEL: nMethod = M_Cancel; aMethod = CUniString("Cancel"); break;
368                                             case BUTTONID_YES: nMethod = M_Yes; aMethod = CUniString("Yes"); break;
369                                             case BUTTONID_NO: nMethod = M_No; aMethod = CUniString("No"); break;
370                                             case BUTTONID_RETRY: nMethod = M_Repeat; aMethod = CUniString("Repeat"); break;
371                                             case BUTTONID_HELP: nMethod = M_Help; aMethod = CUniString("Help"); break;
372                                             default: nMethod = M_Click; aMethod = CUniString("Click");
373                                         }
374                                         if ( m_bRecord )
375                                         {
376                                             if ( nMethod != M_Click )
377                                                 StatementList::pRet->GenReturn( RET_MacroRecorder, UID_ACTIVE, nMethod );
378                                             else
379                                                 StatementList::pRet->GenReturn( RET_MacroRecorder, UID_ACTIVE, nMethod, (comm_ULONG)nCurrentButtonId );
380                                             bSendData = sal_True;
381                                         }
382                                         if ( m_bLog )
383                                         {
384                                             if ( nMethod != M_Click )
385                                                 LogVCL( rtl::OString(), pWin->GetType(), pWin->GetUniqueOrHelpId(), aMethod );
386                                             else
387                                                 LogVCL( rtl::OString(), pWin->GetType(), pWin->GetUniqueOrHelpId(), aMethod, nCurrentButtonId );
388                                             bDone = sal_True;
389                                         }
390                                     }
391                                     break;
392                                 default:
393                                     {
394                                         comm_USHORT nMethod;
395                                         String aMethod;
396                                         switch ( pWin->GetType() )
397                                         {
398                                             case WINDOW_OKBUTTON: nMethod = M_OK; aMethod = CUniString("OK"); break;
399                                             case WINDOW_CANCELBUTTON: nMethod = M_Cancel; aMethod = CUniString("Cancel"); break;
400                                             case WINDOW_HELPBUTTON: nMethod = M_Help; aMethod = CUniString("Help"); break;
401                                             default: nMethod = M_Default;aMethod = CUniString("Unknown Button");
402                                                 DBG_ERROR( "Unknown Button" );
403                                         }
404                                         if ( m_bRecord )
405                                         {
406                                             StatementList::pRet->GenReturn( RET_MacroRecorder, pParent->GetUniqueOrHelpId(), nMethod );
407                                             bSendData = sal_True;
408                                         }
409                                         if ( m_bLog )
410                                         {
411                                             LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), aMethod );
412                                             bDone = sal_True;
413                                         }
414                                     }
415                                     break;
416                             }
417                         }
418                         if ( m_bRecord )
419                         {
420                             if ( !bSendData && pWin->GetUniqueOrHelpId().getLength() )
421                             {
422                                 StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), (comm_USHORT)M_Click );
423                                 bSendData = sal_True;
424                             }
425                         }
426                         if ( m_bLog )
427                         {
428                             if ( !bDone )
429                                 LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), CUniString("Click") );
430                         }
431                 }
432                 break;
433 /*          case C_MoreButton:
434                 switch( nEventID )
435                 {
436                     case M_IsOpen :
437                         pRet->GenReturn ( RET_Value, nUId, ((MoreButton*)pControl)->GetState());
438                         break;
439                     case M_Click :
440                         ((MoreButton*)pControl)->Click();
441                         break;
442                     case M_Open :
443                         ((MoreButton*)pControl)->SetState(sal_True);
444                         break;
445                     case M_Close :
446                         ((MoreButton*)pControl)->SetState(sal_False);
447                         break;
448                     default:
449                         ReportError( nUId, GEN_RES_STR2c2( S_UNKNOWN_METHOD, MethodString(nMethodId), "MoreButton" ) );
450                         break;
451                 }
452                 break;*/
453             case WINDOW_SPINFIELD:
454             case WINDOW_PATTERNFIELD:
455             case WINDOW_NUMERICFIELD:
456             case WINDOW_METRICFIELD:
457             case WINDOW_CURRENCYFIELD:
458             case WINDOW_DATEFIELD:
459             case WINDOW_TIMEFIELD:
460                 switch( nEventID )
461                 {
462                     case VCLEVENT_SPINFIELD_UP:
463                     case VCLEVENT_SPINFIELD_DOWN:
464                     case VCLEVENT_SPINFIELD_FIRST:
465                     case VCLEVENT_SPINFIELD_LAST:
466                         {
467                             pEditModify = NULL;
468                             aEditModifyString.Erase();
469 
470                             comm_USHORT nMethod;
471                             String aMethod;
472                             switch ( nEventID )
473                             {
474                                 case VCLEVENT_SPINFIELD_UP: nMethod = M_More; aMethod = CUniString("More"); break;
475                                 case VCLEVENT_SPINFIELD_DOWN: nMethod = M_Less; aMethod = CUniString("Less"); break;
476                                 case VCLEVENT_SPINFIELD_FIRST: nMethod = M_ToMin; aMethod = CUniString("ToMin"); break;
477                                 case VCLEVENT_SPINFIELD_LAST: nMethod = M_ToMax; aMethod = CUniString("ToMax"); break;
478                                 default: nMethod = M_ToMin; aMethod = CUniString("Unknown");
479                                     DBG_ERROR( "Unknown EventID in Spinfield" );
480                             }
481                             if ( m_bRecord )
482                             {
483                                 StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), nMethod );
484                                 bSendData = sal_True;
485                             }
486                             if ( m_bLog )
487                             {
488                                 LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), aMethod );
489                             }
490                         }
491                         break;
492                     case VCLEVENT_EDIT_MODIFY:
493                         pEditModify = pWin;
494                         aEditModifyString = ((SpinField*)pWin)->GetText();
495                         break;
496                 }
497                 break;
498 
499             case WINDOW_MENUBUTTON:
500                     switch( nEventID )
501                     {
502                     case VCLEVENT_BUTTON_CLICK:
503                         if ( m_bRecord )
504                         {
505                             StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), (comm_USHORT)M_Click );
506                             bSendData = sal_True;
507                         }
508                         if ( m_bLog )
509                         {
510                             LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), CUniString("Click") );
511                         }
512                         break;
513 /*      Keyevent or Timeout
514                     case M_Open :
515                         {
516                             MouseEvent aMEvnt;
517                             Point aPt( pControl->GetSizePixel().Width() / 2, pControl->GetSizePixel().Height() / 2 );
518                             aMEvnt = MouseEvent( aPt,1,MOUSE_SIMPLECLICK,MOUSE_LEFT );
519                             ImplMouseButtonDown( pControl, aMEvnt );
520 
521                             sal_uLong nStart = Time::GetSystemTicks();
522                             sal_uLong nDelay = pControl->GetSettings().GetMouseSettings().GetActionDelay();
523                             while ( ( Time::GetSystemTicks() - nStart ) < nDelay + 100 )
524                                 SafeReschedule();
525 
526                             ImplMouseButtonUp  ( pControl, aMEvnt );
527                         }
528                         break;*/
529                     }
530                 break;
531             case WINDOW_TOOLBOX:
532                 {
533                     ToolBox *pTB = ((ToolBox*)pWin);
534                     switch( nEventID )
535                     {
536                         case VCLEVENT_TOOLBOX_SELECT:
537                             {   // a Button has been clicked
538                                 // so this cannot be a tearoff or OpenMenu anymore
539                                 pActionParent = NULL;
540                                 // compare to 1 for floating ToolBoxes
541                                 if ( m_bRecord )
542                                 {
543                                     if ( !pWin->GetUniqueOrHelpId().getLength() /* || pWin->GetUniqueOrHelpId().Matches( 1 ) */ )
544                                         // generate direct Button access
545                                         StatementList::pRet->GenReturn( RET_MacroRecorder, Str2Id( pTB->GetItemCommand( pTB->GetCurItemId() ) ), (comm_USHORT)(M_Click) );
546                                     else
547                                         // access via Toolbox
548                                         StatementList::pRet->GenReturn( RET_MacroRecorder, pTB->GetUniqueOrHelpId(), (comm_USHORT)(M_Click|M_RET_NUM_CONTROL), Id2Str( pTB->GetHelpId( pTB->GetCurItemId() ) ) );
549                                     bSendData = sal_True;
550                                 }
551 /* not needed                               if ( m_bLog )
552                                 {
553                                 }*/
554                             }
555                             break;
556                         case VCLEVENT_TOOLBOX_CLICK:  /// ATTENTION this is called during initialisation of toolbox. whoever 'invented' this
557                             pActionParent = pTB;
558                             break;
559 //                        case VCLEVENT_WINDOW_SHOW:        // not usable ATM. see above
560 //                            if ( pActionParent )
561 //                            {   // a new toolbox opens up, might be a tearoff
562 //                                if ( pActionParent != pWin )
563 //                                {   // it IS a tearoff not an undock
564 //                                    // compare to 1 for floating ToolBoxes
565 //                                  if ( m_bRecord )
566 //                                  {
567 //                                      if ( !pWin->GetSmartUniqueOrHelpId().HasAny() || pWin->GetSmartUniqueOrHelpId().Matches( 1 ) )
568 //                                          // generate direct Button access
569 //                                          StatementList::pRet->GenReturn( RET_MacroRecorder, rtl::OString( pActionParent->GetHelpId( pActionParent->GetCurItemId() ) ), (comm_USHORT)(M_TearOff) );
570 //                                      else
571 //                                          // access via Toolbox
572 //                                          StatementList::pRet->GenReturn( RET_MacroRecorder, pActionParent->GetSmartUniqueOrHelpId(), (comm_USHORT)(M_TearOff|M_RET_NUM_CONTROL), static_cast<comm_ULONG>(pActionParent->GetHelpId( pActionParent->GetCurItemId() )) ); // GetHelpId() sal_uLong != comm_ULONG on 64bit
573 //                                      bSendData = sal_True;
574 //                                  }
575 //                                    if ( m_bLog )
576 //                                    {
577 //                                        LogVCL( pActionParent->GetSmartUniqueOrHelpId(), pWin->GetType(), pActionParent->GetHelpId( pActionParent->GetCurItemId() ), CUniString("TearOff") );
578 //                                    }
579 //                                }
580 //                                pActionParent = NULL;
581 //                            }
582 //                            break;
583                         case VCLEVENT_TOOLBOX_DEACTIVATE:
584                             pActionParent = NULL;
585                             break;
586                     }
587                 }
588                 break;
589 /*                  ToolBox *pTB = ((ToolBox*)pControl);
590                     if ( pTB->GetUniqueOrHelpId() != nUId ) // Also Button auf der ToolBox gefunden
591                     {
592                         if ( nParams == PARAM_NONE )
593                         {           // Wir f�lschen einen Parameter
594                             nParams = PARAM_USHORT_1;
595                             nNr1 = nUId;
596                         }
597                         else
598                             ReportError( nUId, GEN_RES_STR1( S_INTERNAL_ERROR, MethodString( nMethodId ) ) );
599                     }
600 
601 #define FIND_HELP\
602 {\
603     if( nParams == PARAM_USHORT_1 )\
604         nLNr1 = nNr1;\
605     for ( nNr1 = 0; nNr1 < pTB->GetItemCount() && nLNr1 != pTB->GetHelpId(pTB->GetItemId(nNr1)) ; nNr1++ ) {}\
606     bBool1 = nLNr1 == pTB->GetHelpId(pTB->GetItemId(nNr1));\
607     if ( !bBool1 )\
608         ReportError( nUId, GEN_RES_STR1( S_HELPID_ON_TOOLBOX_NOT_FOUND, MethodString( nMethodId ) ) );\
609     else\
610     {\
611         if ( !pTB->IsItemEnabled( pTB->GetItemId(nNr1) ) && nMethodId != _M_IsEnabled )\
612         {\
613             ReportError( nUId, GEN_RES_STR1( S_BUTTON_DISABLED_ON_TOOLBOX, MethodString( nMethodId ) ) );\
614             bBool1 = sal_False;\
615         }\
616         else if ( !pTB->IsItemVisible( pTB->GetItemId(nNr1) ) )\
617         {\
618             ReportError( nUId, GEN_RES_STR1( S_BUTTON_HIDDEN_ON_TOOLBOX, MethodString( nMethodId ) ) );\
619             bBool1 = sal_False;\
620         }\
621         else\
622         {\
623             if ( pTB->GetItemRect(pTB->GetItemId(nNr1)).IsEmpty() )\
624             {\
625                 sal_uInt16 nLine = pTB->GetCurLine();\
626                 do\
627                 {\
628                     pTB->ShowLine( sal_False );\
629                     for ( int i = 1 ; i < 30 ; i++ )\
630                         SafeReschedule();\
631                 }\
632                 while ( pTB->GetCurLine() != nLine && pTB->GetItemRect(pTB->GetItemId(nNr1)).IsEmpty() );\
633                 pTB->Invalidate( pTB->GetScrollRect() );\
634             }\
635             if ( pTB->GetItemRect(pTB->GetItemId(nNr1)).IsEmpty() )\
636             {\
637                 ReportError( nUId, GEN_RES_STR1( S_CANNOT_MAKE_BUTTON_VISIBLE_IN_TOOLBOX, MethodString( nMethodId ) ) );\
638                 bBool1 = sal_False;\
639             }\
640         }\
641     }\
642 }\
643 
644                     switch( nEventID )
645                     {
646                         case M_SetNextToolBox :
647                             if ( (nParams & PARAM_STR_1) )
648                                 pTB->SetNextToolBox( aString1 );
649                             else
650                                 pTB->SetNextToolBox( pTB->GetNextToolBox() );
651                             pTB->NextToolBox();
652                             break;
653                         case M_GetNextToolBox :
654                             pRet->GenReturn ( RET_Value, nUId, (String)pTB->GetNextToolBox());
655                             break;
656                         default:
657                             ReportError( nUId, GEN_RES_STR2c2( S_UNKNOWN_METHOD, MethodString(nMethodId), "ToolBox" ) );
658                             break;
659                     }
660                 }
661                 break;
662 */
663             case WINDOW_CONTROL:
664             case WINDOW_WINDOW:
665                 switch( nEventID )
666                 {
667                     case VCLEVENT_WINDOW_COMMAND:
668                         break;
669                     case VCLEVENT_WINDOW_KEYINPUT:
670                         {
671                             const KeyEvent *pKeyEvent = ((KeyEvent*)pWinEvent->GetData());
672                             const KeyCode aKeyCode = pKeyEvent->GetKeyCode();
673                             if ( pKeyEvent )
674                             {
675                                 pKeyWin = pWin;
676                                 Window *pIdWin = GetParentWithID( pWin );
677                                 if ( pIdWin != pWin )
678                                    bKeyFollowFocus = sal_True;
679                                 aKeyUniqueID = pIdWin->GetUniqueOrHelpId();
680                                 if ( m_bLog )
681                                 {
682 //   HACK Too many KeyEvents generated                                 if ( aKeyString.Len() == 0 )
683 //   HACK Too many KeyEvents generated                                     LogVCL( rtl::OString(), 0, aKeyUniqueID, CUniString("TypeKeysStart") );
684                                 }
685                                 if ( ( !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) &&
686                                       (( aKeyCode.GetGroup() == KEYGROUP_NUM)   ||
687                                        ( aKeyCode.GetGroup() == KEYGROUP_ALPHA) ||
688                                        ( aKeyCode.GetCode() == KEY_SPACE) ||
689                                        ( aKeyCode.GetCode() == KEY_ADD) ||
690                                        ( aKeyCode.GetCode() == KEY_SUBTRACT) ||
691                                        ( aKeyCode.GetCode() == KEY_MULTIPLY) ||
692                                        ( aKeyCode.GetCode() == KEY_DIVIDE) ||
693                                        ( aKeyCode.GetCode() == KEY_POINT) ||
694                                        ( aKeyCode.GetCode() == KEY_COMMA) ||
695                                        ( aKeyCode.GetCode() == KEY_EQUAL) ||
696                                        ( aKeyCode.GetCode() == 0) ) )
697                                 {
698                                     DBG_ASSERT( pKeyEvent->GetCharCode(), "no charcode found" );
699                                     aKeyString += pKeyEvent->GetCharCode();
700                                 }
701                                 else
702                                 {   // not a regular key, transfer KeyCode
703                                     aKeyString += sal_Unicode(1);   // mask it
704                                     // extra for '>' which is coded as <SHIFT GREATER>
705                                     if ( pKeyEvent->GetCharCode() == '>' )
706                                         aKeyString += sal_Unicode( KEY_GREATER | (aKeyCode.GetAllModifier() & ~KEY_SHIFT) );
707                                     else
708                                         aKeyString += sal_Unicode( aKeyCode.GetCode() | aKeyCode.GetAllModifier() );
709                                 }
710                             }
711                         }
712                         break;
713 
714                     case VCLEVENT_WINDOW_MOUSEMOVE:
715                     case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
716                     case VCLEVENT_WINDOW_MOUSEBUTTONUP:
717                         {
718                         }
719                         break;
720 
721 
722                 }
723                 break;
724             case WINDOW_DOCKINGWINDOW:
725 //                switch( nEventID )
726                 {
727 //                  case 1 .. 0xffff:
728     DBG_TRACE3( "TT_VCLMessage %u %u  %X",nEventID, pWin->GetType(), pWin );
729 //                      sal_Bool bx = ((DockingWindow*)pWin)->IsFloatingMode();
730 //                      break;
731 /*                  case M_Dock :
732                         if ( ((DockingWindow*)pControl)->IsFloatingMode() )
733                             ((DockingWindow*)pControl)->SetFloatingMode(sal_False);
734                         else
735                             ReportError( nUId, GEN_RES_STR1( S_ALLOWED_ONLY_IN_FLOATING_MODE, MethodString( nMethodId ) ) );
736                         break;
737                     case M_Undock :
738                         if ( !((DockingWindow*)pControl)->IsFloatingMode() )
739                             ((DockingWindow*)pControl)->SetFloatingMode(sal_True);
740                         else
741                             ReportError( nUId, GEN_RES_STR1( S_ALLOWED_ONLY_IN_FLOATING_MODE, MethodString( nMethodId ) ) );
742                         break;
743                     case M_IsDocked :
744                         pRet->GenReturn ( RET_Value, nUId, (comm_BOOL) !((DockingWindow*)pControl)->IsFloatingMode());
745                         break;
746                     case M_Close:
747                             //nWindowWaitUId = nUId;
748                         DBG_ASSERT( nUId == pControl->GetUniqueOrHelpId(), "nUID != UniqueOrHelpId");
749                         SET_WINP_CLOSING(pControl);
750                         ((DockingWindow*)pControl)->Close();
751                         break;
752                     case M_Size:
753                     case M_Move:
754                     case M_IsMax :
755                     case M_Minimize :
756                     case M_Maximize :
757                         if ( ((DockingWindow*)pControl)->IsFloatingMode() )
758                         {
759                             pControl = ((DockingWindow*)pControl)->GetFloatingWindow();
760                             goto FloatWin;
761                         }
762                         else
763                             ReportError( nUId, GEN_RES_STR1( S_ALLOWED_ONLY_IN_DOCKING_MODE, MethodString( nMethodId ) ) );
764                         break;
765                     case M_Help:        // Alles was unten weiterbehandelt werden soll
766                         goto MoreDialog;
767 
768                     default:
769                         ReportError( nUId, GEN_RES_STR2c2( S_UNKNOWN_METHOD, MethodString(nMethodId), "DockingWindow" ) );
770                         break;*/
771                 }
772                 break;
773 
774 
775 
776 
777 
778 
779             case WINDOW_FLOATINGWINDOW:
780                 {
781     DBG_TRACE3( "TT_VCLMessage %u %u  %X",nEventID, pWin->GetType(), pWin );
782 //                    FloatingWindow *pFW = ((FloatingWindow*)pWin);
783 /*                  switch( nEventID )
784                     {
785 
786 // M_OpenMenu an einem ToolboxButton
787                         case VCLEVENT_WINDOW_SHOW:
788                             if ( pActionParent )
789                             {   // a new FloatingWindow opens up, so we assume an OpenMenu
790                                 // compare to 1 for floating ToolBoxes
791                                 if ( ( pActionParent->GetUniqueOrHelpId() == 0 || pActionParent->GetUniqueOrHelpId() == 1 ) )
792                                     // generate direct Button access
793                                     StatementList::pRet->GenReturn( RET_MacroRecorder, pActionParent->GetHelpId( pActionParent->GetCurItemId() ), (comm_USHORT)(M_OpenMenu) );
794                                 else
795                                     // access via Toolbox
796                                     StatementList::pRet->GenReturn( RET_MacroRecorder, pActionParent->GetUniqueOrHelpId(), (comm_USHORT)(M_OpenMenu|M_RET_NUM_CONTROL), pActionParent->GetHelpId( pActionParent->GetCurItemId() ) );
797                                 bSendData = sal_True;
798                             }
799                             break;
800 
801                     }
802   */              }
803                 break;
804 /*
805                     case M_AnimateMouse :
806                         AnimateMouse( pControl, MitteOben);
807                         break;
808                     case M_IsMax :
809                         pRet->GenReturn ( RET_Value, nUId, (comm_BOOL)!((FloatingWindow*)pControl)->IsRollUp());
810                         break;
811                     case M_Minimize :
812                         ((FloatingWindow*)pControl)->RollUp();
813                         break;
814                     case M_Maximize :
815                         ((FloatingWindow*)pControl)->RollDown();
816                         break;
817                     case M_Size:
818                     {
819                         if ( pControl->GetStyle() & WB_SIZEABLE )
820                         {
821                             pControl->SetSizePixel(Size(nNr1,nNr2));
822                             pControl->Resize();
823                         }
824                         else
825                             ReportError( nUId, GEN_RES_STR1( S_SIZE_NOT_CHANGEABLE, MethodString( nMethodId ) ) );
826                         break;
827                     }
828                     case M_Close:
829                         DBG_ASSERT( nUId == pControl->GetUniqueOrHelpId(), "nUID != UniqueOrHelpId");
830                         SET_WINP_CLOSING(pControl);
831                         ((FloatingWindow*)pControl)->Close();
832                         break;
833                     case M_Help:        // Alles was unten weiterbehandelt werden soll
834                     case M_Move:
835                         goto MoreDialog;
836                     default:
837                         ReportError( nUId, GEN_RES_STR2c2( S_UNKNOWN_METHOD, MethodString(nMethodId), "FloatingWin" ) );
838                         break;
839                 }
840                 break;*/
841 
842 
843 
844 
845 
846 
847 
848 
849 /*
850             case C_ModelessDlg:
851             case C_Dlg:
852             case C_TabDlg:
853                 MoreDialog:
854                 switch( nEventID )
855                 {
856 
857                     // (Rect GetRect)
858 
859                     case M_AnimateMouse :
860                         AnimateMouse( pControl, MitteOben);
861                         break;
862                     case M_Close:
863                         DBG_ASSERT( nUId == pControl->GetUniqueOrHelpId(), "nUID != UniqueOrHelpId");
864                         SET_WINP_CLOSING(pControl);
865                         ((SystemWindow*)pControl)->Close();
866                         break;
867                     case M_Move:
868                     {
869                         pControl->SetPosPixel(Point(nNr1,nNr2));
870                         break;
871                     }
872                     default:
873                         ReportError( nUId, GEN_RES_STR2c2( S_UNKNOWN_METHOD, MethodString(nMethodId), "Dialog" ) );
874                         break;
875                 }
876                 break;*/
877 
878 
879 
880 
881 
882 
883 
884 
885 
886 
887 
888 
889 
890 /*
891             case C_WorkWin:
892                 switch( nEventID )
893                 {
894                     case M_Close:
895                         DBG_ASSERT( nUId == pControl->GetUniqueOrHelpId(), "nUID != UniqueOrHelpId");
896                         SET_WINP_CLOSING(pControl);
897                         ((WorkWindow*)pControl)->Close();
898                         break;
899                     case M_Size:
900                     case M_Move:
901                         goto FloatWin;
902                         break;
903                     case M_Help:        // Alles was unten weiterbehandelt werden soll
904                         goto MoreDialog;
905                     default:
906                         ReportError( nUId, GEN_RES_STR2c2( S_UNKNOWN_METHOD, MethodString(nMethodId), "WorkWindow" ) );
907                         break;
908                 }
909                 break;
910   */
911 
912 
913 /*          case C_TabPage:
914                 switch( nEventID )
915                 {
916                 }
917                 break;*/
918 
919 
920 
921 
922 
923 
924 
925 
926 
927 
928 
929 
930 
931 /*
932             case C_MessBox:
933             case C_InfoBox:
934             case C_WarningBox:
935             case C_ErrorBox:
936             case C_QueryBox:
937                 {
938                     sal_Bool bDone = sal_True;
939                     MessBox* pMB = (MessBox*)pControl;
940                     switch( nEventID )
941                     {
942                         case M_GetCheckBoxText:
943                             pRet->GenReturn ( RET_Value, nUId, pMB->GetCheckBoxText() );
944                             break;
945                         case M_IsChecked :
946                             pRet->GenReturn ( RET_Value, nUId, comm_BOOL( pMB->GetCheckBoxState() == STATE_CHECK) );
947                             break;
948                         case M_GetState :
949                             pRet->GenReturn ( RET_Value, nUId, comm_ULONG( pMB->GetCheckBoxState() ));
950                             break;
951                         case M_Check :
952                             pMB->SetCheckBoxState( STATE_CHECK );
953                             break;
954                         case M_UnCheck :
955                             pMB->SetCheckBoxState( STATE_NOCHECK );
956                             break;
957                         case M_GetText :
958                             pRet->GenReturn ( RET_Value, nUId, pMB->GetMessText());
959                             break;
960 
961                         default:
962                             bDone = sal_False;
963                             break;
964                     }
965                     if ( bDone )
966                         break;  // break the case here else continue at C_ButtonDialog
967                 }
968             case C_ButtonDialog:
969                 {
970                     ButtonDialog* pBD = (ButtonDialog*)pControl;
971 #if OSL_DEBUG_LEVEL > 1
972                     m_pDbgWin->AddText( "Working MessBox: " );
973                     if (pControl->IsVisible())
974                         m_pDbgWin->AddText("*(Visible)\n");
975                     else
976                         m_pDbgWin->AddText("*(nicht Visible)\n");
977 #endif
978                     switch( nEventID )
979                     {
980                         case M_GetText :
981                             pRet->GenReturn ( RET_Value, nUId, pControl->GetText());
982                             break;
983                         case M_Click:
984                             if ( nParams & PARAM_USHORT_1 )
985                             {
986                                 if ( pBD->GetPushButton( nNr1 ) )
987                                 {
988                                     if ( nNr1 != BUTTONID_HELP )
989                                     {
990                                         SET_WINP_CLOSING(pControl);
991                                     }
992                                     pBD->GetPushButton( nNr1 )->Click();
993                                 }
994                                 else
995                                     ReportError( nUId, GEN_RES_STR2( S_NO_DEFAULT_BUTTON, UniString::CreateFromInt32( nNr1 ), MethodString( nMethodId ) ) );
996                             }
997                             else
998                                 ReportError( nUId, GEN_RES_STR1( S_BUTTONID_REQUIRED, MethodString( nMethodId ) ) );
999                             break;
1000                         case M_GetButtonCount :
1001                             pRet->GenReturn ( RET_Value, nUId, comm_ULONG(pBD->GetButtonCount()));
1002                             break;
1003                         case M_GetButtonId :
1004                             if ( ValueOK(nUId, MethodString( nMethodId ),nNr1,pBD->GetButtonCount()) )
1005                                 pRet->GenReturn ( RET_Value, nUId, comm_ULONG(pBD->GetButtonId(nNr1-1)));
1006                             break;
1007                         default:
1008                             ReportError( nUId, GEN_RES_STR2c2( S_UNKNOWN_METHOD, MethodString(nMethodId), "MessageBox" ) );
1009                             break;
1010                     }
1011                     break;
1012 
1013 
1014                  */
1015 
1016 
1017         }
1018 
1019 
1020         switch( nEventID )
1021         {
1022             case VCLEVENT_CONTROL_LOSEFOCUS:
1023                 if ( pEditModify == pWin )
1024                 {
1025                     if ( m_bRecord )
1026                     {
1027                         StatementList::pRet->GenReturn( RET_MacroRecorder, pWin->GetUniqueOrHelpId(), M_SetText, aEditModifyString );
1028                         bSendData = sal_True;
1029                     }
1030                     if ( m_bLog )
1031                     {
1032                         LogVCL( GetParentID( pWin ), pWin->GetType(), pWin->GetUniqueOrHelpId(), CUniString("Modify") );
1033                     }
1034                     pEditModify = NULL;
1035                     aEditModifyString.Erase();  //could be somewhat lengthy
1036                 }
1037                 break;
1038         }
1039 
1040         pLastWin = pWin;
1041 
1042     }  // if
1043     else if ( pEvent->ISA( VclMenuEvent ) )
1044     {
1045 //        VclMenuEvent* pMenuEvent = ( VclMenuEvent* ) pEvent;
1046     }
1047 
1048 
1049     if ( bSendData )
1050         new StatementFlow( NULL, F_EndCommandBlock );   // Kommando zum Senden erzeugen und in que eintragen
1051 
1052     return 0;
1053 }
1054 
1055 
1056 
1057 static ::osl::Mutex * getRecorderMutex()
1058 {
1059     static ::osl::Mutex * pMutex  = NULL;
1060     if(pMutex==NULL)
1061     {
1062         ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
1063         if(pMutex==NULL)
1064             pMutex = new ::osl::Mutex();
1065     }
1066     return pMutex;
1067 }
1068 
1069 
1070 void MacroRecorder::CheckDelete()
1071 {
1072     ::osl::MutexGuard aGuard( getRecorderMutex() );
1073     if ( !m_bRecord && !m_bLog )
1074     {
1075         pMacroRecorder = NULL;
1076         delete this;
1077     }
1078 }
1079 
1080 
1081 MacroRecorder* MacroRecorder::GetMacroRecorder()
1082 {
1083     ::osl::MutexGuard aGuard( getRecorderMutex() );
1084     if ( !pMacroRecorder )
1085         pMacroRecorder = new MacroRecorder;
1086 
1087     return pMacroRecorder;
1088 }
1089 
1090 sal_Bool MacroRecorder::HasMacroRecorder()
1091 {
1092     ::osl::MutexGuard aGuard( getRecorderMutex() );
1093     return pMacroRecorder != NULL;
1094 }
1095 
1096