xref: /trunk/main/automation/source/server/server.cxx (revision ffd38472365e95f6a578737bc9a5eb0fac624a86)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_automation.hxx"
24 
25 // do not use Application Idle but AutoTimer instead
26 #define TIMERIDLE
27 
28 #define NO_JPEG
29 
30 #ifndef NO_JPEG
31 #include <svtools/jpeg.hxx>
32 #endif
33 #include <vcl/timer.hxx>
34 #include <vcl/wrkwin.hxx>
35 #include <osl/diagnose.h>
36 #include <osl/mutex.hxx>
37 
38 #ifndef _DIALOG_HXX //autogen
39 #include <vcl/dialog.hxx>
40 #endif
41 #include <tools/stream.hxx>
42 #include <tools/config.hxx>
43 
44 #include <vos/socket.hxx>
45 
46 #if 1
47 #include <svtools/ttprops.hxx>
48 #include <basic/ttstrhlp.hxx>
49 #include <svl/stritem.hxx>
50 #include <svtools/stringtransfer.hxx>
51 #include <vcl/sound.hxx>
52 #include "testtool.hrc"
53 #include <vcl/bitmap.hxx>
54 // Hat keinen Includeschutz
55 #include <svtools/svtdata.hxx>
56 //#ifndef _DTRANS_HXX //autogen
57 //#include <so2/dtrans.hxx>
58 //#endif
59 #endif // 1
60 #include <rtl/textenc.h>
61 #include <rtl/uri.h>
62 #include <rtl/uri.hxx>
63 #include "statemnt.hxx"
64 #include "scmdstrm.hxx"
65 #include "rcontrol.hxx"
66 #include "server.hxx"
67 #include "testtool.hxx"
68 #include "automation/automation.hxx"
69 #include "recorder.hxx"
70 
71 #include "basic/svtmsg.hrc"
72 
73 #ifdef DBG_UTIL
74 void TestToolDebugPrint( const sal_Char *pString )
75 {
76     if ( !DbgFilterMessage( pString ) )
77         StatementList::DirectLog( S_AssertError, UniString( pString, RTL_TEXTENCODING_UTF8 ) );
78 }
79 void SAL_CALL osl_TestToolDebugPrint( const sal_Char *pString )
80 {
81     TestToolDebugPrint( pString );
82 }
83 #endif
84 
85 
86 sal_uLong RemoteControlCommunicationManager::nPortIs = TT_PORT_NOT_INITIALIZED;
87 sal_uInt16 RemoteControlCommunicationManager::nComm = 0;
88 sal_Bool RemoteControlCommunicationManager::bQuiet = sal_False;
89 
90 #if OSL_DEBUG_LEVEL > 1
91 RemoteControlCommunicationManager::RemoteControlCommunicationManager( EditWindow * pDbgWin )
92 #else
93 RemoteControlCommunicationManager::RemoteControlCommunicationManager()
94 #endif
95 : CommunicationManagerServerViaSocket( GetPort(), 1, sal_True )
96 #if OSL_DEBUG_LEVEL > 1
97 , m_pDbgWin( pDbgWin )
98 #endif
99 , pTimer( NULL )
100 {
101     bIsPortValid = ( GetPort() != 0 );
102     if ( bQuiet )
103     {
104         SetInfoType( CM_NO_TEXT );
105     }
106     else
107     {
108         SetInfoType( CM_SHORT_TEXT | CM_ALL );
109         ByteString aByteString;
110         InfoMsg( InfoString( aByteString, CM_ALL ) );   // Anzeigen, da� wir da sind
111     }
112 }
113 
114 RemoteControlCommunicationManager::~RemoteControlCommunicationManager()
115 {
116     if ( pTimer )
117         delete pTimer;
118     DoQuickShutdown();
119 }
120 
121 void RemoteControlCommunicationManager::ConnectionOpened( CommunicationLink* pCL )
122 {
123     StatementFlow::pCommLink = pCL;
124     CommunicationManagerServerViaSocket::ConnectionOpened( pCL );
125 }
126 
127 
128 void RemoteControlCommunicationManager::ConnectionClosed( CommunicationLink* pCL )
129 {
130     StatementFlow::pCommLink = NULL;
131     CommunicationManagerServerViaSocket::ConnectionClosed( pCL );
132 }
133 
134 
135 IMPL_LINK( RemoteControlCommunicationManager, SetWinCaption, Timer*, EMPTYARG )
136 {
137     if ( pTimer )
138     {
139         delete pTimer;
140         pTimer = NULL;
141     }
142 
143     if ( StatementList::GetFirstDocFrame() )
144     {
145         if ( !aOriginalWinCaption.Len() )
146             aOriginalWinCaption = StatementList::GetFirstDocFrame()->GetText();
147         StatementList::GetFirstDocFrame()->SetText(String(aOriginalWinCaption).AppendAscii(" TT").Append(aAdditionalWinCaption).AppendAscii("[").Append(UniString::CreateFromInt32(nPortToListen)).AppendAscii("]"));
148     }
149     else
150     {   // Dann Probieren wir es eben in 1 Sekunde nochmal
151         pTimer = new Timer(); // Wird im Link gel�scht
152         pTimer->SetTimeout( 1000 );
153         pTimer->SetTimeoutHdl( LINK( this, RemoteControlCommunicationManager, SetWinCaption ) );
154         pTimer->Start();
155     }
156     return 0;
157 }
158 
159 void RemoteControlCommunicationManager::InfoMsg( InfoString aMsg )
160 {
161     if ( !bIsPortValid )
162         return;
163     aAdditionalWinCaption = UniString( aMsg, RTL_TEXTENCODING_ASCII_US );
164     SetWinCaption();
165 #if OSL_DEBUG_LEVEL > 1
166     m_pDbgWin->AddText( UniString( (ByteString)aMsg, RTL_TEXTENCODING_ASCII_US ) );
167     m_pDbgWin->AddText( "\n" );
168 #endif
169 }
170 
171 sal_uLong RemoteControlCommunicationManager::GetPort()
172 {
173     if ( TT_PORT_NOT_INITIALIZED == nPortIs )
174     {   // Read Config
175 
176         sal_uInt16 i;
177         // are we to be automated at all?
178         sal_Bool bAutomate = sal_False;
179         for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
180         {
181             if ( Application::GetCommandLineParam( i ).EqualsIgnoreCaseAscii("/enableautomation")
182                 || Application::GetCommandLineParam( i ).EqualsIgnoreCaseAscii("-enableautomation"))
183             {
184                 bAutomate = sal_True;
185                 break;
186             }
187         }
188     // Get port from command line
189     if (bAutomate)
190     {
191         for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
192         {
193             if ( Application::GetCommandLineParam( i ).Copy(0,16).EqualsIgnoreCaseAscii("/automationport=")
194                 || Application::GetCommandLineParam( i ).Copy(0,16).EqualsIgnoreCaseAscii("-automationport="))
195             {
196                         nPortIs = Application::GetCommandLineParam( i ).Copy(16).ToInt32();
197                         return nPortIs;
198             }
199             }
200     }
201     //
202 // if started within Portal determin location of testtool.ini/rc by analysing the commandline
203 // /userid:demo1[/export/home/user/demo1]
204 // -userid:demo1[/export/home/user/demo1]
205         String aIniFileDir;
206         for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
207         {
208             if ( Application::GetCommandLineParam( i ).Copy(0,8).EqualsIgnoreCaseAscii("/userid:")
209                 || Application::GetCommandLineParam( i ).Copy(0,8).EqualsIgnoreCaseAscii("-userid:") )
210             {
211                 rtl::OUString aEncHome
212                     = Application::GetCommandLineParam(i).GetBuffer();
213 
214                 rtl::OUString aDecHome = rtl::Uri::decode(aEncHome,
215                         rtl_UriDecodeWithCharset,
216                         RTL_TEXTENCODING_UTF8);
217 
218                 aIniFileDir = aDecHome;
219                 aIniFileDir.Erase( 0, aIniFileDir.Search('[')+1 );
220                 aIniFileDir.Erase( aIniFileDir.Search(']') );
221             }
222         }
223 
224         if ( ! aIniFileDir.Len() )
225             aIniFileDir = Config::GetDefDirectory();
226 
227         Config aConf(Config::GetConfigName( aIniFileDir, CUniString("testtool") ));
228         aConf.SetGroup("Communication");
229 
230         ByteString aNoTesttoolKey( ByteString("Exclude_").Append( ByteString( Application::GetAppFileName(), RTL_TEXTENCODING_UTF8 ) ) );
231 // -notesttool
232         for ( i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
233         {
234             if ( Application::GetCommandLineParam( i ).CompareIgnoreCaseToAscii("-notesttool") == COMPARE_EQUAL )
235                 aConf.WriteKey( aNoTesttoolKey, "something" );
236         }
237 
238         nPortIs = aConf.ReadKey("TTPort","0").ToInt32();
239 
240         // noch pr�fen ob dieses Office getestet werden soll.
241         if ( !bAutomate || aConf.ReadKey( aNoTesttoolKey, "" ) != "" )
242             nPortIs = 0;
243 
244         nComm = (sal_uInt16)aConf.ReadKey("Comm","0").ToInt32();
245         if ( nComm )
246             aConf.DeleteKey("Comm");
247 
248         bQuiet = ( aConf.ReadKey("Quiet","no").CompareIgnoreCaseToAscii("yes") == COMPARE_EQUAL );
249     }
250     return nPortIs;
251 }
252 
253 #if OSL_DEBUG_LEVEL > 1
254 #define MIN_IDLE 10000      // Ruhe vor dem Sturm min 10 Sekunden
255 #else
256 #define MIN_IDLE 60000      // Ruhe vor dem Sturm min 1 Minuten
257 #endif
258 
259 class ExtraIdle : public AutoTimer
260 {
261     virtual void    Timeout();
262 
263     sal_uInt16 nStep;
264     ImplRemoteControl *pRemoteControl;
265 public:
266     ExtraIdle( ImplRemoteControl *pRC );
267 };
268 
269 
270 ExtraIdle::ExtraIdle( ImplRemoteControl *pRC )
271 : nStep( 0 )
272 , pRemoteControl (pRC )
273 {
274     SetTimeout( 120000 );   // 2 Minuten
275 #if OSL_DEBUG_LEVEL > 1
276     SetTimeout( 40000 );    // 40 Sekunden
277 #endif
278     Start();
279 }
280 
281 void ExtraIdle::Timeout()
282 {
283     if ( !StatementList::pTTProperties )
284         StatementList::pTTProperties = new TTProperties();
285 
286     if ( !StatementList::pTTProperties->GetSlots() )
287     {
288         delete this;
289         return;
290     }
291 
292     // M�ssen wir selbst idlen?
293 #if OSL_DEBUG_LEVEL > 1
294     sal_uLong nLastInputInterval = Application::GetLastInputInterval();
295     sal_Bool bIsInModalMode = Application::IsInModalMode();
296     if ( bIsInModalMode || nLastInputInterval < MIN_IDLE )
297 #else
298     if ( Application::IsInModalMode() || Application::GetLastInputInterval() < MIN_IDLE )
299 #endif
300     {
301         if ( nStep )    // Schon angefangen? dann abbrechen, sonst sp�ter nochmal
302         {
303             if ( nStep < 15 )
304             {
305                 Sound::Beep();
306                 Sound::Beep();
307             }
308 #if OSL_DEBUG_LEVEL < 2
309             delete this;
310 #endif
311         }
312 #if OSL_DEBUG_LEVEL > 1
313         if ( nStep < 15 )
314         {
315             Sound::Beep();
316             Sound::Beep();
317         }
318 #endif
319         return;
320     }
321 
322     if ( StatementList::pFirst )    // Verarbeitung neu aufsetzen
323     {
324         GetpApp()->PostUserEvent( LINK( pRemoteControl, ImplRemoteControl, CommandHdl ) );
325         return;
326     }
327 
328 
329     switch ( nStep++ )      // Probieren ob wir noch was machen k�nnen
330     {
331         case 0:
332         {
333             SfxPoolItem *pItem = new SfxStringItem((sal_uInt16)StatementList::pTTProperties->nSidNewDocDirect, CUniString("swriter/web") );
334             new StatementSlot( StatementList::pTTProperties->nSidNewDocDirect, pItem );
335             SetTimeout(30000);
336             return;
337         }
338         case 1:
339         {
340             new StatementSlot( StatementList::pTTProperties->nSidSourceView );
341 #if OSL_DEBUG_LEVEL > 1
342             SetTimeout(7000);
343 #else
344             SetTimeout(1500);
345 #endif
346             return;
347         }
348         case 2:
349         {
350             new StatementSlot( StatementList::pTTProperties->nSidSelectAll );
351             return;
352         }
353         case 3:
354         {
355 
356 #if OSL_DEBUG_LEVEL > 1
357 //#define TT_NO_DECRYPT
358 #define TT_CODE
359 #else
360 #define TT_CODE
361 #endif
362 
363 #ifdef TT_NO_DECRYPT
364             String aStr =
365                 ""
366                 ;
367 
368 #else
369             ByteString aStr =
370                 "\n"
371                 "VRQJ`ob\n"
372                 "YEZO\n"
373                 "ob\n"
374                 "UmRo`\n"
375                 "5J~O2o5+90~5,6xW$+5:c9o0UXRm`Y UQ~JP~X]`Y\\|%Y`Yo]~O||2[pP0Y1J,|V),,7:,+|JS+U*[/O|K\n"
376                 "|KaLYNV~]]2W/]*Y9|`*Y,P=[5P|U\n"
377                 "]}mqbw`zZU\\L\n"
378                 "LZdYWo9\n"
379                 "/J\n"
380                 "U~[QoZ\n"
381                 "Rqd~V\n"
382                 ",)1~00\n"
383                 "\n"
384                 ")0~*2=\n"
385                 "++2\\5&K|~5n9r~9/*9<*~051*Q|0~0rY|~./97~Q*7,Z9<|KY0:=K*<=w~qY`IbOKzLwN,`7b,V~]E`]b\\ORE~\n"
386                 "\n"
387                 "Vq~bR`W;a+Y\\J=LKJa+W*I/PbR~JLUX[|b~`Z2P/R*[9a~W=9~/9p8=a*P=J0OZ~7L`JbL=P<WbaLQbPO]JYKbD\n"
388                 "aY`J5J:b~7=2~+9)9W1,50b9X3P0`YbYVJ`Jb  \\`Z]`Vb\n"
389                 "VRQJ`b"
390                 ;
391 #endif
392 
393 #ifdef TT_CODE
394             for ( sal_uInt16 i = 0 ; i < aStr.Len() ; i++ )
395             {
396                 if ( aStr.GetChar(i) < 32 || aStr.GetChar(i) > 126 )
397                 {
398                     // do nothing
399                 }
400                 else
401                 {
402                     aStr.SetChar( i, aStr.GetChar(i) - 32 );
403                     aStr.SetChar( i, 126 - aStr.GetChar(i) );
404                 }
405 
406                 if ( i > (aStr.Len() / 2) && (i&1) )
407                 {
408                     sal_Char c = aStr.GetChar(i);
409                     aStr.SetChar( i, aStr.GetChar(aStr.Len()-i-1) );
410                     aStr.SetChar( aStr.Len()-i-1, c );
411                 }
412             }
413 #endif
414 
415             ::svt::OStringTransfer::CopyString( UniString( aStr, RTL_TEXTENCODING_ASCII_US ), StatementList::GetFirstDocFrame()  );
416 
417             new StatementSlot( StatementList::pTTProperties->nSidPaste );
418             return;
419         }
420         case 4:
421         {
422             new StatementSlot( StatementList::pTTProperties->nSidSourceView );
423             return;
424         }
425         case 5:
426         {
427             new StatementSlot( StatementList::pTTProperties->nSidSelectAll );
428             new StatementSlot( StatementList::pTTProperties->nSidCopy );
429             new StatementSlot( StatementList::pTTProperties->nSidPaste );
430             return;
431         }
432         case 6:
433         {
434             ByteString aTr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-");
435             ByteString aData =
436 "P-S-0U04Fihixh00l0004b0b300-PS0g30428333y243q334j44426a6a65576c8k97aJecf7feccedg2inj3ghlshde5krk+lno"
437 "PpqpBfjsgusp1unp-po-PS0gm044x465e6b6L6boygeg-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo-ooo"
438 "-ooo-ooo-oo-1M04020Y30J0o080B040R040M-N0M700l010l000k000000000006000N011I112r222M-N0gJ40D000U001R011"
439 "0110500vr0001014p148mcg1R4koV18s95cwkAE2V8gImM5kgQY9WcosCw22I556p669I99aoaadrddd6eeeNghhIhhiriik6lll"
440 "NlmmImoprppp6qqqNsttItturuuw6xxxNxyyHyAA6BBBNBCCHCEE6FFFNFGGHGII6JJJNJKKHKMM6NNNNNOOHOQQ6RRRNRSSCSUU"
441 "NUVVIVVWpWWYIYYZrZZZ6+++M-N0Q700R000l000l000g00000006000N011I112r222M-N0kJ40C0003110d1110110r00t6000"
442 "Q041l18cF14gtk1ous48Acw295gAlEIMv28cxkY5FosQE2595dU9sY56q669N9aaCaddNdeeIeghrhhh6iiiNkllIllmrmmo6ppp"
443 "NpqqIqstrttt6uuuIwwxrxxx6yyyIAABrBBB6CCCIEEFrFFF6GGGIIIJrJJJ6KKKIMMNrNNN6OOOIQQRrRRR6SSSIUUVrVVV6WWW"
444 "IYYZrZZZ6+++U-S0d3009004Q040Of0TPU5QGjFCdPoji85WiqEopkCag321kP8dW4yO4KRlNi9iwzeTKup+Yk0lrdcicCEeLtVQ"
445 "z1IFeROmSJBa7VYMYY-0EWGkJWH6LpAVdrUepM7ScEpkTBkenX3YGuoFVU0IGk+dSzPpv0N6U07eTPFgid-YtvOD2ws5C96qDgIL"
446 "vhsoWmBPAozc+KgPjiVuW0TJnrt6PqF63p2VJEJ6A+l33JqESWh0G4yn1JkcaaEBnw17xmaf0q4BGkVy40Jj+FAyioG3KEukCtP1"
447 "OAdOe4ASVCPuUrQDFsqBoRWN6jqxOBfH-30WbgyZy+HtyI6xNVvt3M0lnfscjA8rBUeoRXifTPCceY6t46AR9ooG2jVzdmo+PQ6R"
448 "cAEDd7VE3GvUyDJzn2e0yyzypEdnCzUZorT029pk4LHJYsRQmR5smaW9EuCbt2A2s2Nd9ZKAkcJSWoTGPV5p6d1PZCiYt6kVETBB"
449 "K7zNWhRK7kMBCag7zELQ2e6HWHM+BwO4nJA-30uF2a2WgcgndWuk6gPbha0D5WFPq902KmjNwyg5xkVQvgd9W9SCfiFd95Ndh9yj"
450 "Odd7k38da3xWqtwcHPOEb7AvIPqAdRbz3XNNEYFu7bS9Iz-0UVQJc-gtgPCQ7cledmoGTULsGpjeu0TzkJi2tusMDnR4cisDw2rz"
451 "Vhs36hPC0oSH7V-UMAjVIC3dRFwNoc20a0+Culnm3q9QQJsgt00IeEoRXCh3jUg3eO8yGBOpFwYap5OrpoAfMeR6Q8L0sUIgI7B3"
452 "Oy9q5WMBAxg5PYnBSxZlywhwDlb45Il6Y+F-NaH62MEoByaq02d2aaEz5Bwx45DqfEC4ACqd4FYjI9IbAgqH7uFopm+JQRSHrSNd"
453 "ct0dwNo+FAUaD926b3wtUoRIPJ-MTLLiQcC92bTBue9RkDqqYRcXxn06S9Jm6Qhpk9IjH8JLyIinJj3EAF7bTH9jkf170OvzuO2j"
454 "I2jenHhQvnKoDSHSmWenEhfEHkVgekpfIOhkBhqLVaEvb83EyfD2Awrbk5+lwyvOne6yBA36rdrmna4xFOsvqGxRcgcJy-lXnjCn"
455 "eeWhGvqAbmSf7LcDwqykK9jqADpRqkXSq7MB7ZOHSgJhNitiw3i6y9LYjRNlq4Lc-00zCNL3CThC65Ajjlw8550bAbqa0d0Jz3BT"
456 "kH6EDgQhRUhjtyK9y9CjraNEw9ERUq6MmYa989nsRqsPxo+zi2IbOfxy9q3lFL-QSWn5qwp7nTFUwVe-XaDxnGfWOIYXXfIkILs-"
457 "lWPSm51tjj967w11u-YylxUO++EfuLsmr1c3jLdgcDYmK9roIAmz1t1vAalje3oyXDp335xkQ24rS1JhdokOn5cWpizqiE5bsbg4"
458 "4gWkfJ2IEVnSoWmj8eNeAFuoT0wzWWm9UgmDKRH2INGJy6OHTwn7zawsiPo796yQd6OsPORlTrUR-bEMLPj8nZdMwyX-Jb8npd2-"
459 "zV9JMRdNarUy1aF0tiihB0o+kQh5iy9r9BMqhPjf+WckJ9WWqmSQTEqAl+zwgw-+vH5WomSNVjbDLchO9Ae-ggdQGPcb+7Dq0X-d"
460 "XsFHj76-a0eUqKlN6cgHMKgKSmv8xcMVnCIPAnqR0SsThTWe8GSgo3pTGWTgBrtb1X2OfHMHsi8D3gkpPwKvoxoEuSJcTmD2kiAS"
461 "Pk3wl5C5NZDe9OrZMdDg6VQpDybXJ7EWLCdwsPoTGqhcGOGvrJ2WgFuuem+wP1ZGhkpee9rU7CTad9q9DxVgNzGWk+lGid6rKswa"
462 "1+Uc57RmFASpo3qbaGvuMReTLCWXsocM6lvXmSZHAhhaaV7EHH9sJglnrUlniII4I0gVZHFLys8VKKb2yKbAYHeSY3VlmgRywmqd"
463 "UXugq90wSsh0poya0qEAF9CjjadQumckue1unyK1sdcUwyxQOcARlHjLWYd3lS2ozCTQ48zZXesU66bAUfTdoXoOInm7MpPgwiDp"
464 "XDqJrEMEChxb747KzIHfxSdi++EwdRNK7RHEmgVhqiZkW1WqBEnjst6Oz08ztIPVknfPjq8NDB4h9g1sD+l1xQNzHNg+Jb1Vmii6"
465 "1dP-57LPdOhlWSTKYaCmzwAhGqyOlPrY9zXZodpZuoL2kjTBLBxaeGcM+NONZcN7GqIqFcNlhVgMXKHsd-WEBBR957ZZn7hk-mbb"
466 "FGxWLzaiHE6t48mXupNDlxi6d1w-yaPlmczA0gTsEhqRrsEbj48ProNvyivlaY06bdYSvGN7IOBc1ezBJiFd5OTz+RbzIsqJpCsJ"
467 "BOTSLjAdwXCzq-XExGbygb3X2oURVXxTB4q0e6euBRnXkIJuTM7SfQfQkdEEjN7J56t3oxP6B0cA4lgSDhURzsDzrkk0ECxfwaU3"
468 "ovagJuvzx07aksPdxkQ8aqEy618F-4wjCr3hZq8gq3gu7RJ4ovXa86R7ZskSYJC01o2OpfvJh0WqpYiIuE0zBqpI3kTJQZ0Or5ku"
469 "9RzhbzbV1AU0BzJ5vPTOBRIOIAiJiBiOdI8fR3dcWle3xCder+W6QELyr6NaldJipQCeAMwRr5mpzZESGAhuU3BDdkCh5ENgMUE-"
470 "sWotoCfnOwT7tJlXLHODk8K7Z4zYCG9Dh2fQazDE0JqBDruomfatotGADn25BCDpk6GI6SSftpUd71Qr1JBrgOr33aWswl983Uk7"
471 "cq9Em7vGtACekHlvOOVJfbdh76nNHzuQ1Z1oBvuU9l-dAg+-QWWFQ18D8U+zmYn1jypyarIXSrcIb67wLDTFXWm8F9XPmFWRBD3d"
472 "WukVJwhGNV5ZHVE1wCudY07ZIEAd1kgzgPcRSxFhRhFpXsnESjJhUNCA3DlrARwzz+llg0xpVHrJiddYT36P453qxpOmIE9e6-qJ"
473 "h4ipfTTt8f2Kq4mdWniErPtI+wrN-edvCQFtPdrL+tpV6EpPRXgmHnjRhV0eWWzqxdRZacX98CME3pvwDYWkO8TOUlcNQSKTU1iF"
474 "FC9WIBA8PulsCFVNH1qJwZxYYcaX6CGNnR7vHiIBDsTE51J4b4fYucNYFG9V5mCUdrJT57tHk9eghSOfgeHZDxuvQt8619pwKma7"
475 "3Nl00EFklZOk+APRmKviL+iyiG1sWfA3E0xUPznlQgvsHJRzD9u0TzHsB6tIMKLmOxvVHG9knpHerjAXNqIp7jwZzvYXIyW8kw8g"
476 "3ycECFaB2Y2U0l00NE7l2Aca2y5uhk+QJygN0857SQMVSEXjy+Q84nQjkTh1GAtFACtdHRhwQ6FhQMLjFu6zyxuFycbQA7qNSsiy"
477 "90wlAaUBBtFhxMV0TPd8DbVScjJoMSAYMh6GhAHnKOZsbdqvwtHKdZWZ9HQbdmVOt0xnnK5Ju9KfwhuHMZIoPt73BqspII6qBobB"
478 "5kfcwm183j4fwapcs50EoGgz2UZGuK88agfskePeYt9DOQD3qxxfuJ5lZUFHa8aqFJIT6MG2Kwtwuu0zBqTz8x5DYM7PDh29F9FU"
479 "1ge-wqqIMqmXlpbO65sila1be1yRGABAbw2njF5txZEAaqEyEo9FUPqnKQ4y1NQqSXkCpsqpO06UUCyBBzaDjawwoHkKOT1-zqpz"
480 "FU7JNudONE3fuYk83U9thALoAIeG6FKizOLgU4AcDcszCmGZgylUI-Edd9mAKL9nJe+YdiYxl7uX4mATdO30KcuDrRoTxBbiHbuA"
481 "qlorQn1D0opRuIhzVLm8+z8QRFlNA0683M1QYE+Lhka+kaIDvE8RHQHel4bOsMFp6lmV6D3cNhQvpG1sECm02a5tgF52reEBaYEw"
482 "OhD+RQiFedTm3OQg5iq2c04kidOoDgaPNGs1VitbrhIvAuzStaWksap3jp9UrAN1O-0nAECIfSP0QHVkGWtduz6XSmJ7MsLPmPJ3"
483 "hRjY7DtZXWjvtHcj9ooAXcPsI+3YgG951n7urnyB1kbQV+ZdlAbI11Y3orBMB+le8goi66fWyEX9FHpFEL32jNqSghzvyEC1227-"
484 "p5t8vx19mYHbOghy5K7voWUAXsjX2gwzicmKiNJR9OrHppAbVEVzVjOuYWmwCpGWFW1DlaoOc03PWkgqvVeezQY8IiM9Rptnniwf"
485 "Xa1XnMPo6ES0MHE5nwC8tT65VVw3C2peCu720i6oVvevcoMGeP3PVgvBkudifs0GNH7AaOGVFhrbE68B8sq6AH8BFvXhZfzdhb1f"
486 "Y1p-GVyr3qECy393zFEq0wHg2Vls4OiVD-J0d7JFKsuhUPgdykTCWhbqkdvwUUyg7qXPvdeC09AUAszRcVsk5iihIr1+N-0ATkGU"
487 "i6GPwTlzw-dALNmjbVjHOSAsWaihe303RxAmD4akSPWkjgtot17BTZfaSgaNH+ESoUGJ3GgPJqD8UBsAShIF-X0wwyFpDkTwESHg"
488 "jNwUF9EpszCwj1myzqZG9hIp76G1ymz7BuZF0T5pdA1GMG8AGuRbXEtJMkHsDJoztG06Jqm-khFPydXg-VB1k+l9AMwzzvtCDacK"
489 "k22WU1fByYcDpmW0Y9YF-zeZDDcQJVF8tT8cNNjt9GdIF3103ZFP8oulWCfnXETCKz3YQFsm3qOUu6GJ-lb2foo1WJqGpcCbyPmy"
490 "Ib95rQLJnk56YC1KmN5zMJ831cVsERyvdPOSW8kg-2uk8m3J4zgAWAhvvBOofIjFb5yNf0shVv-JJ9f49ZFcQ+LKDFKX3iNV1E-G"
491 "MxeEwbi-uGP8BGO4vGgV0IFbgswumfhk14OF3q+1qwRFpq4hr1s6zQEAgoVAW3QE4tsQpYW3JkcqDcnSOjbePZeFrFMor-o3UG2F"
492 "jmw8667eXk3UiM9vq5EpyrbQxexsJ3tKy7w6lGsumfMWIlcSglkLUzicysuPgqT5Wuzn8MkGvTYve2UyunErUnD-+Qwr0rDo1tOG"
493 "bbtcNNeFInx5rDK3DHahjTON3d3oTpePxioVK3sRLDh185yKMzTQv812ADCFcwvFHbetPF41f7kot00O2OMUkw4OPvuTRkhdAhgd"
494 "il2SM9bunNaNHqh9Ov8Qv3SKEl1O-BwzjYF0VWjkxycswQFqQotUPw+Q-6FrCPFWvaF2CP2F319stMfD-8bHsd87KZfQ9ChereG4"
495 "Z8XP8dNMipn-evkOVVFqfgN16dO8Ya9nqGFIpIW1Ljv7wOAzdZFsm5C1EuQoKzwyXDO0BDjceBsyTt40H0upG8D1N1ZP66OPIeQy"
496 "oXQwI63e+NnuYA0687-d6N6rDscj+VHn2R0RUXQFZ2+EANqcqvan4y0Erpl01fAfmLaI8pmOgsRUDvuF5e9YnWNhxtSzS4fsjj1J"
497 "1EIGpcw0WfiaOul1s19ZIECoLBx-#S";
498 
499 
500 //#if OSL_DEBUG_LEVEL > 1
501 //          SvFileStream aStream( "d:\\gh_writeback.jpg" , STREAM_STD_READWRITE | STREAM_TRUNC );
502 //#else
503             SvMemoryStream aStream;
504 //#endif
505             xub_StrLen c;
506             xub_StrLen cRest = 0;
507 
508             xub_StrLen nIndex;
509             for ( nIndex = 0 ; nIndex < aData.Len() ; nIndex++ )
510             {
511                 if ( ( nIndex & 3 ) == 0 )
512                 {
513                     cRest = aData.GetChar( nIndex );
514                     cRest = aTr.Search( (sal_Char)cRest );
515                 }
516                 else
517                 {
518                     c = aData.GetChar( nIndex );
519                     c = aTr.Search( (sal_Char)c );
520 
521                     c <<= 2;
522                     c |= ( ( cRest & 0x30 ) >> 4 );
523                     cRest <<= 2;
524 
525                     aStream << sal_Char(c);
526                 }
527             }
528 
529             aStream.Seek(0);
530 #ifndef NO_JPEG
531             Graphic aGraphic;
532             if ( ImportJPEG( aStream, aGraphic, NULL ) )
533             {
534                 Bitmap *pBmp = new Bitmap( aGraphic.GetBitmap() );
535                 StatementList::pTTProperties->Img( pBmp );
536                 delete pBmp;
537             }
538             else
539 #endif
540             {
541                 ::svt::OStringTransfer::CopyString( CUniString("\nSorry! no bitmap"), StatementList::GetFirstDocFrame() );
542             }
543 
544 /***********************************************************************
545 //          sal_uInt16 nBC = pBmp->GetBitCount();
546 //          pBmp->Scale( 0.02, 0.02 );
547 //          nBC = pBmp->GetBitCount();
548 //          SvMemoryStream aStream;
549             SvFileStream aStream( "d:\gh_small50.jpg", STREAM_STD_READ );
550 
551             aStream.Seek( 0 );
552             xub_StrLen c;
553             String aOut;
554             String aDreierGruppe;
555             xub_StrLen cRest=0;
556             aStream >> c;
557             while ( !aStream.IsEof() )
558             {
559                 cRest <<= 2;        // Im ersten Durchgang egal, da immer 0
560                 cRest |= ( c & 0x03 );
561                 c >>= 2;
562                 aDreierGruppe += aTr.GetChar( c );
563 
564                 if ( aDreierGruppe.Len() == 3 )
565                 {
566                     aOut += aTr.GetChar( cRest );
567                     aOut += aDreierGruppe;
568                     cRest = 0;
569                     aDreierGruppe = "";
570                 }
571                 aStream >> c;
572             }
573             if ( aDreierGruppe.Len() )
574             {
575                 aOut += cRest;
576                 aOut += aDreierGruppe;
577             }
578             ::svt::OStringTransfer::CopyString( aOut );
579 **********************************************************************************/
580 
581             new StatementSlot( StatementList::pTTProperties->nSidPaste );
582             return;
583         }
584         case 7:
585         {
586             new StatementSlot( 20384 ); // FN_TOOL_ANCHOR_CHAR from SW?
587             return;
588         }
589     }
590 
591     // Wir sind am Ende
592 
593 #if OSL_DEBUG_LEVEL < 2
594     delete this;
595 #endif
596 }
597 
598 IMPL_LINK( ImplRemoteControl, IdleHdl, Application*, EMPTYARG )
599 {
600     if( StatementList::pFirst )
601     {
602         #if OSL_DEBUG_LEVEL > 1
603         m_pDbgWin->AddText( "* " );
604         #endif
605         GetpApp()->PostUserEvent( LINK( this, ImplRemoteControl, CommandHdl ) );
606     }
607     return 0;
608 }
609 
610 
611 
612 IMPL_LINK( ImplRemoteControl, CommandHdl, Application*, EMPTYARG )
613 {
614 #if OSL_DEBUG_LEVEL > 1
615     m_pDbgWin->AddText( "Entering CommandHdl\n" );
616 #endif
617 
618     if ( StatementList::MaybeResetSafeReschedule() )
619     {
620         StatementList::bExecuting = sal_False;      // Wird nacher im SafeReschedule wieder zur�ckgesetzt
621 #if OSL_DEBUG_LEVEL > 1
622         m_pDbgWin->AddText( "SafeReschedule has been reset\n" );
623 #endif
624     }
625 
626     if ( ( StatementList::bReadingCommands && !StatementList::bDying ) ||
627          ( StatementList::bExecuting ) ||
628          ( StatementList::IsInReschedule() ) )
629         {
630 #if OSL_DEBUG_LEVEL > 1
631             if ( StatementList::bReadingCommands )
632                 m_pDbgWin->AddText( "Reading Commands " );
633             if ( StatementList::bExecuting )
634                 m_pDbgWin->AddText( "In Execute " );
635             if ( StatementList::IsInReschedule() )
636             {
637                 m_pDbgWin->AddText( "In Reschedule FocusWindow: 0x" );
638                 m_pDbgWin->AddText(
639                         String::CreateFromInt64(
640                             sal::static_int_cast< sal_Int64 >(
641                                 reinterpret_cast< sal_IntPtr >(GetpApp()->GetFocusWindow())),
642                             16 ));
643                                 m_pDbgWin->AddText( " " );
644             }
645             m_pDbgWin->AddText( "Leaving CommandHdl\n" );
646 #endif
647             return 0;        // Garnicht erst irgendwelchen bl�dsinn machen
648         }
649 
650     while( StatementList::pFirst && ( !StatementList::bReadingCommands || StatementList::bDying ) )
651         // Schleift hier bis Befehl nicht zur�ckkommt,
652         // Wird dann rekursiv �ber IdleHdl und PostUserEvent aufgerufen.
653     {
654         m_bInsideExecutionLoop = sal_True;
655 #ifdef TIMERIDLE
656         m_aIdleTimer.Stop();
657         m_aIdleTimer.Start();
658 #endif
659         StatementList *pC = StatementList::pFirst;
660 
661 //      MessBox MB( pMainWin, WB_DEF_OK|WB_OK, "Pause ...", "... und Weiter" );
662 //      MB.Execute();
663 
664         if ( !StatementList::bCatchGPF )
665         {
666             if (!pC->CheckWindowWait()  ||  !pC->Execute())
667             {
668 #if OSL_DEBUG_LEVEL > 1
669                 m_pDbgWin->AddText( "Leaving CommandHdl\n" );
670 #endif
671                 return 0;        // So dass die App nochmal �ne chance bekommt
672             }
673         }
674         else
675         {
676             try
677             {
678                 if (!pC->CheckWindowWait()  ||  !pC->Execute())
679                 {
680 #if OSL_DEBUG_LEVEL > 1
681                     m_pDbgWin->AddText( "Leaving CommandHdl\n" );
682 #endif
683                     return 0;        // So dass die App nochmal �ne chance bekommt
684                 }
685             }
686             catch( ... )
687             {
688                 if ( !StatementFlow::bUseIPC )
689                     throw;  // aus der Hilfe heraus nicht leise abbrechen
690 
691                 try
692                 {
693                     ModelessDialog *pDlg = new ModelessDialog(NULL);
694                     pDlg->SetOutputSizePixel(Size(150,0));
695                     pDlg->SetText( String ( TTProperties::GetSvtResId( TT_GPF ) ) );
696                     pDlg->Show();
697                     DBG_ERROR("GPF");
698                     pC->ReportError( GEN_RES_STR0( S_GPF_ABORT ) );
699                     StatementList::bDying = sal_True;
700                     while ( StatementList::pFirst )         // Kommandos werden �bersprungen
701                         StatementList::NormalReschedule();
702                     delete pDlg;
703                 }
704                 catch ( ... )
705                 {
706                     Application::Quit();
707                 }
708                 Application::Quit();
709             }
710         }
711 
712 /*  #i46293# remove reschedules
713         for (int xx = 1;xx < 20;xx++)
714             StatementList::NormalReschedule();
715 */
716         m_bInsideExecutionLoop = sal_False;
717     }
718 
719     StatementList::aWindowWaitUId = rtl::OString();  // Warten r�cksetzen, da handler sowieso verlassen wird
720 
721 /*    if( StatementList::pFirst && !StatementList::bReadingCommands )
722          // Abfrage n�tig, da andere CommandHdl aktiv sein k�nnen oder
723          // neue Commands gelesen werden k�nnen
724     {
725         delete StatementList::pFirst;     // L�scht die gesamte Liste !!
726         StatementList::pFirst   = NULL;
727         StatementList::pCurrent = NULL;   // Nur zur Sicherheit, sollte hier sowieso NULL sein
728     }*/
729 
730 #if OSL_DEBUG_LEVEL > 1
731     m_pDbgWin->AddText( "Leaving CommandHdl\n" );
732 #endif
733     return 0;
734 }
735 
736 IMPL_LINK( ImplRemoteControl, QueCommandsEvent, CommunicationLink*, pCL )
737 {
738     SvStream *pTemp = pCL->GetServiceData();
739     QueCommands( SI_IPCCommandBlock, pTemp );
740     delete pTemp;
741     return 0;
742 }
743 
744 sal_Bool ImplRemoteControl::QueCommands( sal_uLong nServiceId, SvStream *pIn )
745 {
746 //  return sal_True;
747     sal_uInt16 nId;
748 
749     if( !m_bIdleInserted )
750     {
751 #ifdef TIMERIDLE
752         m_aIdleTimer.SetTimeoutHdl( LINK( this, ImplRemoteControl, IdleHdl ) );
753         m_aIdleTimer.SetTimeout( 500 );
754         m_aIdleTimer.Start();
755 #else
756         GetpApp()->InsertIdleHdl( LINK( this, ImplRemoteControl, IdleHdl ), 1 );
757 #endif
758         m_bIdleInserted = sal_True;
759     }
760 
761 
762     StatementList::bReadingCommands = sal_True;
763 
764 #if OSL_DEBUG_LEVEL > 1
765     if (!m_pDbgWin->bQuiet)
766         m_pDbgWin->Show();
767     m_pDbgWin->AddText( "Reading " );
768     m_pDbgWin->AddText( String::CreateFromInt64( nServiceId ) );
769     m_pDbgWin->AddText( " :\n" );
770 #endif
771 
772     if( nServiceId != SI_IPCCommandBlock && nServiceId != SI_DirectCommandBlock )
773     {
774         DBG_ERROR1( "Ung�ltiger Request :%i", (int)nServiceId );
775         return sal_False;
776     }
777 
778     SCmdStream *pCmdStream = new SCmdStream(pIn);
779 
780     pCmdStream->Read( nId );
781     while( !pIn->IsEof() )
782     {
783         switch( nId )
784         {
785             case SICommand:
786             {
787                 new StatementCommand( pCmdStream ); // Wird im Konstruktor an Liste angeh�ngt
788                 break;
789             }
790             case SIControl:
791             case SIStringControl:
792             {
793                 new StatementControl( pCmdStream, nId ); // Wird im Konstruktor an Liste angeh�ngt
794                 break;
795             }
796             case SISlot:
797             {
798                 new StatementSlot( pCmdStream ); // Wird im Konstruktor an Liste angeh�ngt
799                 break;
800             }
801             case SIUnoSlot:
802             {
803                 new StatementUnoSlot( pCmdStream ); // Wird im Konstruktor an Liste angeh�ngt
804                 break;
805             }
806             case SIFlow:
807             {
808                 new StatementFlow( nServiceId, pCmdStream, this ); // Wird im Konstruktor an Liste angeh�ngt
809                 break;
810             }
811             default:
812                 DBG_ERROR1( "Unbekannter Request Nr:%i", nId );
813                 break;
814         }
815         if( !pIn->IsEof() )
816             pCmdStream->Read( nId );
817         else {
818             DBG_ERROR( "truncated input stream" );
819         }
820     }
821 
822     StatementList::bReadingCommands = sal_False;
823 
824     delete pCmdStream;
825 #if OSL_DEBUG_LEVEL > 1
826     m_pDbgWin->AddText( "Done Reading " );
827     m_pDbgWin->AddText( String::CreateFromInt64( nServiceId ) );
828     m_pDbgWin->AddText( " :\n" );
829 #endif
830     if ( !m_bInsideExecutionLoop )
831     {
832 #ifdef DEBUG
833         m_pDbgWin->AddText( "Posting Event for CommandHdl.\n" );
834 #endif
835 
836         GetpApp()->PostUserEvent( LINK( this, ImplRemoteControl, CommandHdl ) );
837     }
838 #ifdef DEBUG
839     else
840         m_bInsideExecutionLoop = sal_True;
841 #endif
842     return sal_True;
843 } // sal_Bool ImplRemoteControl::QueCommands( sal_uLong nServiceId, SvStream *pIn )
844 
845 
846 SvStream* ImplRemoteControl::GetReturnStream()
847 {
848     SvStream* pTemp = pRetStream;
849     pRetStream = NULL;
850     return pTemp;
851 }
852 
853 ImplRemoteControl::ImplRemoteControl()
854 : m_bIdleInserted( sal_False )
855 , m_bInsideExecutionLoop( sal_False )
856 #if OSL_DEBUG_LEVEL > 1
857 , m_pDbgWin(NULL)
858 #endif
859 , pRetStream(NULL)
860 {
861 #if OSL_DEBUG_LEVEL > 1
862     if ( RemoteControlCommunicationManager::GetPort() != TT_NO_PORT_DEFINED || RemoteControlCommunicationManager::nComm )
863     {
864         m_pDbgWin = new EditWindow( NULL, CUniString("Debug Window"), WB_VSCROLL );
865         m_pDbgWin->bQuiet = sal_True;
866         m_pDbgWin->Hide();
867         m_pDbgWin->bQuiet = sal_False;
868         m_pDbgWin->Show();
869 
870         StatementList::m_pDbgWin = m_pDbgWin;
871     }
872 #endif
873     if ( RemoteControlCommunicationManager::GetPort() == TT_NO_PORT_DEFINED )
874         pServiceMgr = NULL;
875     else
876     {
877 #if OSL_DEBUG_LEVEL > 1
878         pServiceMgr = new RemoteControlCommunicationManager( m_pDbgWin );
879 #else
880         pServiceMgr = new RemoteControlCommunicationManager();
881 #endif
882         pServiceMgr->SetDataReceivedHdl( LINK( this, ImplRemoteControl, QueCommandsEvent ) );
883         pServiceMgr->StartCommunication();
884 
885 #ifdef DBG_UTIL
886         DbgSetPrintTestTool( TestToolDebugPrint );
887         // first change it, so we get the original Pointer
888         StatementCommand::pOriginal_osl_DebugMessageFunc = osl_setDebugMessageFunc( osl_TestToolDebugPrint );
889         if ( DbgGetErrorOut() != DBG_OUT_TESTTOOL )
890             osl_setDebugMessageFunc( StatementCommand::pOriginal_osl_DebugMessageFunc );
891 #endif
892     }
893     if ( RemoteControlCommunicationManager::nComm )
894         new ExtraIdle( this );      // Setzt die Bearbeitung wieder auf
895 }
896 
897 ImplRemoteControl::~ImplRemoteControl()
898 {
899     if ( MacroRecorder::HasMacroRecorder() )
900         MacroRecorder::GetMacroRecorder()->SetActionRecord( sal_False ); // Will delete MacroRecorder if necessary
901 
902 
903     StatementList::bDying = sal_True;
904 #if OSL_DEBUG_LEVEL > 1
905     if ( m_pDbgWin )
906         m_pDbgWin->bQuiet = sal_True;   // Keine Ausgabe mehr im Debugwindow
907 #endif
908 
909 #ifdef DBG_UTIL
910     // Zur�cksetzen, so da� nachfolgende Assertions nicht verloren gehen
911     DbgSetPrintTestTool( NULL );
912     osl_setDebugMessageFunc( StatementCommand::pOriginal_osl_DebugMessageFunc );
913 #endif
914 
915     if ( StatementList::pFirst )
916     {   // Es sind noch Kommandos da, also auch eine M�glichkeit zur�ckzusenden.
917         StatementList::pFirst->ReportError( GEN_RES_STR0( S_APP_SHUTDOWN ) );
918         while ( StatementList::pFirst )             // Kommandos werden �bersprungen
919             StatementList::NormalReschedule();      // Fehler zur�ckgeschickt
920     }
921 
922     if ( pServiceMgr )
923         pServiceMgr->StopCommunication();
924 
925     if ( GetTTSettings()->pDisplayHidWin )
926     {
927         delete (Window*)(GetTTSettings()->pDisplayHidWin);
928         GetTTSettings()->pDisplayHidWin = NULL;
929     }
930     if ( GetTTSettings()->pTranslateWin )
931     {
932         delete (Window*)(GetTTSettings()->pTranslateWin);
933         GetTTSettings()->pTranslateWin = NULL;
934     }
935 #if OSL_DEBUG_LEVEL > 1
936     delete m_pDbgWin;
937 #endif
938     if( m_bIdleInserted )
939     {
940 #ifdef TIMERIDLE
941         m_aIdleTimer.Stop();
942 #else
943         GetpApp()->RemoveIdleHdl( LINK( this, ImplRemoteControl, IdleHdl ) );
944 #endif
945         m_bIdleInserted = sal_False;
946     }
947     delete pServiceMgr;
948 }
949 
950 RemoteControl::RemoteControl()
951 {
952     pImpl = new ImplRemoteControl;
953 }
954 
955 RemoteControl::~RemoteControl()
956 {
957     delete pImpl;
958 }
959 
960 static ::osl::Mutex aMutex;
961 static RemoteControl* pRemoteControl = 0;
962 extern "C" AUTOMATION_DLLPUBLIC void CreateRemoteControl()
963 {
964     if ( !pRemoteControl )
965     {
966         ::osl::MutexGuard aGuard( aMutex );
967         if ( !pRemoteControl )
968             pRemoteControl = new RemoteControl();
969     }
970 }
971 
972 extern "C" AUTOMATION_DLLPUBLIC void DestroyRemoteControl()
973 {
974     ::osl::MutexGuard aGuard( aMutex );
975     delete pRemoteControl;
976     pRemoteControl = 0;
977 }
978 
979 extern "C" AUTOMATION_DLLPUBLIC void CreateEventLogger()
980 {
981     MacroRecorder::GetMacroRecorder()->SetActionLog();
982 }
983 
984 extern "C" AUTOMATION_DLLPUBLIC void DestroyEventLogger()
985 {
986     MacroRecorder::GetMacroRecorder()->SetActionLog( sal_False ); // Will delete MacroRecorder if necessary
987 }
988 
989 /* vim: set noet sw=4 ts=4: */
990