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_basctl.hxx"
26
27
28 #include <ide_pch.hxx>
29
30
31 #include <svtools/texteng.hxx>
32 #include <svtools/textview.hxx>
33 #include <svtools/xtextedt.hxx>
34 #include <basic/sbx.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
37 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
38 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
39 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
40 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
41 #ifndef _COM_SUN_STAR_SCRIPT_XLIBRYARYCONTAINER2_HPP_
42 #include <com/sun/star/script/XLibraryContainer2.hpp>
43 #endif
44 #include <com/sun/star/document/MacroExecMode.hpp>
45 #include <com/sun/star/script/ModuleType.hpp>
46 #include <toolkit/helper/vclunohelper.hxx>
47 #include <sfx2/docfile.hxx>
48 #include <basic/basrdll.hxx>
49
50
51 #include <baside2.hrc>
52 #include <baside2.hxx>
53 #include <objdlg.hxx>
54 #include <iderdll.hxx>
55 #include <iderdll2.hxx>
56
57 #include <basobj.hxx>
58 #include <brkdlg.hxx>
59
60 #include <svx/srchdlg.hxx>
61
62 #include <vcl/sound.hxx>
63
64 //#ifndef _TXTCMP_HXX //autogen
65 //#include <svtools/txtcmp.hxx>
66 //#endif
67
68 #include <unotools/textsearch.hxx>
69 #include <tools/diagnose_ex.h>
70
71 using namespace ::com::sun::star;
72 using namespace ::com::sun::star::uno;
73
74
75 #define SPLIT_MARGIN 5
76 #define SPLIT_HEIGHT 2
77
78 #define LMARGPRN 1700
79 #define RMARGPRN 900
80 #define TMARGPRN 2000
81 #define BMARGPRN 1000
82 #define BORDERPRN 300
83
84 #define APPWAIT_START 100
85
86 #define VALIDWINDOW 0x1234
87
88 #if defined(OW) || defined(MTF)
89 #define FILTERMASK_ALL "*"
90 #elif defined(PM2)
91 #define FILTERMASK_ALL ""
92 #else
93 #define FILTERMASK_ALL "*.*"
94 #endif
95
96 using namespace ::com::sun::star;
97 using namespace ::com::sun::star::uno;
98 using namespace ::com::sun::star::ui::dialogs;
99 using namespace utl;
100 using namespace comphelper;
101
102
103 DBG_NAME( ModulWindow )
104
105 TYPEINIT1( ModulWindow , IDEBaseWindow );
106
lcl_PrintHeader(Printer * pPrinter,sal_uInt16 nPages,sal_uInt16 nCurPage,const String & rTitle,bool bOutput)107 void lcl_PrintHeader( Printer* pPrinter, sal_uInt16 nPages, sal_uInt16 nCurPage, const String& rTitle, bool bOutput )
108 {
109 short nLeftMargin = LMARGPRN;
110 Size aSz = pPrinter->GetOutputSize();
111 short nBorder = BORDERPRN;
112
113 const Color aOldLineColor( pPrinter->GetLineColor() );
114 const Color aOldFillColor( pPrinter->GetFillColor() );
115 const Font aOldFont( pPrinter->GetFont() );
116
117 pPrinter->SetLineColor( Color( COL_BLACK ) );
118 pPrinter->SetFillColor();
119
120 Font aFont( aOldFont );
121 aFont.SetWeight( WEIGHT_BOLD );
122 aFont.SetAlign( ALIGN_BOTTOM );
123 pPrinter->SetFont( aFont );
124
125 long nFontHeight = pPrinter->GetTextHeight();
126
127 // 1.Border => Strich, 2+3 Border = Freiraum.
128 long nYTop = TMARGPRN-3*nBorder-nFontHeight;
129
130 long nXLeft = nLeftMargin-nBorder;
131 long nXRight = aSz.Width()-RMARGPRN+nBorder;
132
133 if( bOutput )
134 pPrinter->DrawRect( Rectangle(
135 Point( nXLeft, nYTop ),
136 Size( nXRight-nXLeft, aSz.Height() - nYTop - BMARGPRN + nBorder ) ) );
137
138
139 long nY = TMARGPRN-2*nBorder;
140 Point aPos( nLeftMargin, nY );
141 if( bOutput )
142 pPrinter->DrawText( aPos, rTitle );
143 if ( nPages != 1 )
144 {
145 aFont.SetWeight( WEIGHT_NORMAL );
146 pPrinter->SetFont( aFont );
147 String aPageStr( RTL_CONSTASCII_USTRINGPARAM( " [" ) );
148 aPageStr += String( IDEResId( RID_STR_PAGE ) );
149 aPageStr += ' ';
150 aPageStr += String::CreateFromInt32( nCurPage );
151 aPageStr += ']';
152 aPos.X() += pPrinter->GetTextWidth( rTitle );
153 if( bOutput )
154 pPrinter->DrawText( aPos, aPageStr );
155 }
156
157
158 nY = TMARGPRN-nBorder;
159
160 if( bOutput )
161 pPrinter->DrawLine( Point( nXLeft, nY ), Point( nXRight, nY ) );
162
163 pPrinter->SetFont( aOldFont );
164 pPrinter->SetFillColor( aOldFillColor );
165 pPrinter->SetLineColor( aOldLineColor );
166 }
167
lcl_ConvertTabsToSpaces(String & rLine)168 void lcl_ConvertTabsToSpaces( String& rLine )
169 {
170 if ( rLine.Len() )
171 {
172 sal_uInt16 nPos = 0;
173 sal_uInt16 nMax = rLine.Len();
174 while ( nPos < nMax )
175 {
176 if ( rLine.GetChar( nPos ) == '\t' )
177 {
178 // Nicht 4 Blanks, sondern an 4er TabPos:
179 String aBlanker;
180 aBlanker.Fill( ( 4 - ( nPos % 4 ) ), ' ' );
181 rLine.Erase( nPos, 1 );
182 rLine.Insert( aBlanker, nPos );
183 nMax = rLine.Len();
184 }
185 nPos++; // Nicht optimal, falls Tab, aber auch nicht verkehrt...
186 }
187 }
188 }
189
190
ModulWindow(ModulWindowLayout * pParent,const ScriptDocument & rDocument,String aLibName,String aName,::rtl::OUString & aModule)191 ModulWindow::ModulWindow( ModulWindowLayout* pParent, const ScriptDocument& rDocument, String aLibName,
192 String aName, ::rtl::OUString& aModule )
193 :IDEBaseWindow( pParent, rDocument, aLibName, aName )
194 ,aXEditorWindow( this )
195 ,m_aModule( aModule )
196 {
197 DBG_CTOR( ModulWindow, 0 );
198 nValid = VALIDWINDOW;
199 pLayout = pParent;
200 aXEditorWindow.Show();
201
202 SetBackground();
203 }
204
XModule()205 SbModuleRef ModulWindow::XModule()
206 {
207 // ModuleWindows can now be created as a result of the
208 // modules getting created via the api. This is a result of an
209 // elementInserted event from the BasicLibrary container.
210 // However the SbModule is also created from a different listener to
211 // the same event ( in basmgr ) Therefore it is possible when we look
212 // for xModule it may not yet be available, here we keep tring to access
213 // the module until such time as it exists
214
215 if ( !xModule.Is() )
216 {
217 BasicManager* pBasMgr = GetDocument().getBasicManager();
218 if ( pBasMgr )
219 {
220 StarBASIC* pBasic = pBasMgr->GetLib( GetLibName() );
221 if ( pBasic )
222 {
223 xBasic = pBasic;
224 xModule = (SbModule*)pBasic->FindModule( GetName() );
225 }
226 }
227 }
228 return xModule;
229 }
230
~ModulWindow()231 __EXPORT ModulWindow::~ModulWindow()
232 {
233 DBG_DTOR( ModulWindow, 0 );
234 nValid = 0;
235
236 StarBASIC::Stop();
237 }
238
239
GetFocus()240 void __EXPORT ModulWindow::GetFocus()
241 {
242 if ( nValid != VALIDWINDOW )
243 return;
244 DBG_CHKTHIS( ModulWindow, 0 );
245 aXEditorWindow.GetEdtWindow().GrabFocus();
246 // Basisklasse nicht rufen, weil Focus jetzt woanders...
247 }
248
DoInit()249 void ModulWindow::DoInit()
250 {
251 DBG_CHKTHIS( ModulWindow, 0 );
252 // Wird beim Umschalten der Fenster gerufen...
253 if ( GetVScrollBar() )
254 GetVScrollBar()->Hide();
255 GetHScrollBar()->Show();
256 // GetEditorWindow().SetScrollBarRanges();
257 GetEditorWindow().InitScrollBars();
258 // GetEditorWindow().GrabFocus();
259 }
260
261
Paint(const Rectangle &)262 void __EXPORT ModulWindow::Paint( const Rectangle& )
263 {
264 }
265
Resize()266 void __EXPORT ModulWindow::Resize()
267 {
268 aXEditorWindow.SetPosSizePixel( Point( 0, 0 ),
269 Size( GetOutputSizePixel() ) );
270 }
271
272
273 // "Import" von baside4.cxx
274 void CreateEngineForBasic( StarBASIC* pBasic );
275
CheckCompileBasic()276 void ModulWindow::CheckCompileBasic()
277 {
278 DBG_CHKTHIS( ModulWindow, 0 );
279
280 if ( XModule().Is() )
281 {
282 // Zur Laufzeit wird niemals compiliert!
283 sal_Bool bRunning = StarBASIC::IsRunning();
284 sal_Bool bModified = ( !xModule->IsCompiled() ||
285 ( GetEditEngine() && GetEditEngine()->IsModified() ) );
286
287 if ( !bRunning && bModified )
288 {
289 sal_Bool bDone = sal_False;
290
291 BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
292 pIDEShell->GetViewFrame()->GetWindow().EnterWait();
293
294 if( bModified )
295 {
296 AssertValidEditEngine();
297 GetEditorWindow().SetSourceInBasic( sal_False );
298 }
299
300 sal_Bool bWasModified = GetBasic()->IsModified();
301
302 bDone = GetBasic()->Compile( xModule );
303 if ( !bWasModified )
304 GetBasic()->SetModified( sal_False );
305
306 if ( bDone )
307 {
308 GetBreakPoints().SetBreakPointsInBasic( xModule );
309 }
310
311 pIDEShell->GetViewFrame()->GetWindow().LeaveWait();
312
313 aStatus.bError = !bDone;
314 aStatus.bIsRunning = sal_False;
315 }
316 }
317 }
318
BasicExecute()319 sal_Bool ModulWindow::BasicExecute()
320 {
321 DBG_CHKTHIS( ModulWindow, 0 );
322
323 // #116444# check security settings before macro execution
324 ScriptDocument aDocument( GetDocument() );
325 if ( aDocument.isDocument() )
326 {
327 if ( !aDocument.allowMacros() )
328 {
329 WarningBox( this, WB_OK, String( IDEResId( RID_STR_CANNOTRUNMACRO ) ) ).Execute();
330 return sal_False;
331 }
332 }
333
334 CheckCompileBasic();
335
336 if ( XModule().Is() && xModule->IsCompiled() && !aStatus.bError )
337 {
338 if ( GetBreakPoints().Count() )
339 aStatus.nBasicFlags = aStatus.nBasicFlags | SbDEBUG_BREAK;
340
341 if ( !aStatus.bIsRunning )
342 {
343 DBG_ASSERT( xModule.Is(), "Kein Modul!" );
344 AddStatus( BASWIN_RUNNINGBASIC );
345 sal_uInt16 nStart, nEnd, nCurMethodStart = 0;
346 TextSelection aSel = GetEditView()->GetSelection();
347 if ( aDocument.isInVBAMode() )
348 nCurMethodStart = ( aSel.GetStart().GetPara() + 1 );
349 SbMethod* pMethod = 0;
350 // erstes Macro, sonst blind "Main" (ExtSearch?)
351 for ( sal_uInt16 nMacro = 0; nMacro < xModule->GetMethods()->Count(); nMacro++ )
352 {
353 SbMethod* pM = (SbMethod*)xModule->GetMethods()->Get( nMacro );
354 DBG_ASSERT( pM, "Method?" );
355 pM->GetLineRange( nStart, nEnd );
356 if ( aDocument.isInVBAMode() )
357 {
358 if ( nCurMethodStart >= nStart && nCurMethodStart <= nEnd )
359 {
360 pMethod = pM;
361 break;
362 }
363 }
364 else if ( !pMethod || ( nStart < nCurMethodStart && !pM->IsHidden() ) )
365 {
366 pMethod = pM;
367 nCurMethodStart = nStart;
368 }
369 }
370 if ( !pMethod )
371 {
372 if ( aDocument.isInVBAMode() )
373 return ( BasicIDE::ChooseMacro( uno::Reference< frame::XModel >(), sal_False, rtl::OUString() ).isEmpty() == false ) ? sal_True : sal_False;
374 else
375 pMethod = (SbMethod*)xModule->Find( String( RTL_CONSTASCII_USTRINGPARAM( "Main" ) ), SbxCLASS_METHOD );
376 }
377 if ( pMethod )
378 {
379 pMethod->SetDebugFlags( aStatus.nBasicFlags );
380 BasicDLL::SetDebugMode( sal_True );
381 BasicIDE::RunMethod( pMethod );
382 BasicDLL::SetDebugMode( sal_False );
383 // Falls waehrend Interactive=sal_False abgebrochen
384 BasicDLL::EnableBreak( sal_True );
385 }
386 ClearStatus( BASWIN_RUNNINGBASIC );
387 }
388 else
389 aStatus.bIsRunning = sal_False; // Abbruch von Reschedule()
390 }
391
392 sal_Bool bDone = !aStatus.bError;
393
394 return bDone;
395 }
396
CompileBasic()397 sal_Bool ModulWindow::CompileBasic()
398 {
399 DBG_CHKTHIS( ModulWindow, 0 );
400 CheckCompileBasic();
401
402 sal_Bool bIsCompiled = sal_False;
403 if ( XModule().Is() )
404 bIsCompiled = xModule->IsCompiled();
405
406 return bIsCompiled;
407 }
408
BasicRun()409 sal_Bool ModulWindow::BasicRun()
410 {
411 DBG_CHKTHIS( ModulWindow, 0 );
412
413 aStatus.nBasicFlags = 0;
414 sal_Bool bDone = BasicExecute();
415 return bDone;
416 }
417
BasicStepOver()418 sal_Bool ModulWindow::BasicStepOver()
419 {
420 DBG_CHKTHIS( ModulWindow, 0 );
421 aStatus.nBasicFlags = SbDEBUG_STEPINTO | SbDEBUG_STEPOVER;
422 sal_Bool bDone = BasicExecute();
423 return bDone;
424 }
425
426
BasicStepInto()427 sal_Bool ModulWindow::BasicStepInto()
428 {
429 DBG_CHKTHIS( ModulWindow, 0 );
430
431 aStatus.nBasicFlags = SbDEBUG_STEPINTO;
432 sal_Bool bDone = BasicExecute();
433 return bDone;
434 }
435
BasicStepOut()436 sal_Bool ModulWindow::BasicStepOut()
437 {
438 DBG_CHKTHIS( ModulWindow, 0 );
439
440 aStatus.nBasicFlags = SbDEBUG_STEPOUT;
441 sal_Bool bDone = BasicExecute();
442 return bDone;
443 }
444
445
446
BasicStop()447 void ModulWindow::BasicStop()
448 {
449 DBG_CHKTHIS( ModulWindow, 0 );
450
451 GetBasic()->Stop();
452 aStatus.bIsRunning = sal_False;
453 }
454
LoadBasic()455 sal_Bool ModulWindow::LoadBasic()
456 {
457 DBG_CHKTHIS( ModulWindow, 0 );
458 sal_Bool bDone = sal_False;
459
460 Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
461 Reference < XFilePicker > xFP;
462 if( xMSF.is() )
463 {
464 Sequence <Any> aServiceType(1);
465 aServiceType[0] <<= TemplateDescription::FILEOPEN_SIMPLE;
466 xFP = Reference< XFilePicker >( xMSF->createInstanceWithArguments(
467 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ) ), aServiceType ), UNO_QUERY );
468 }
469
470 if ( aCurPath.Len() )
471 xFP->setDisplayDirectory ( aCurPath );
472
473 //xFP->setTitle( String( IDEResId( RID_STR_OPEN ) ) );
474
475 Reference< XFilterManager > xFltMgr(xFP, UNO_QUERY);
476 xFltMgr->appendFilter( String( RTL_CONSTASCII_USTRINGPARAM( "BASIC" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "*.bas" ) ) );
477 xFltMgr->appendFilter( String( IDEResId( RID_STR_FILTER_ALLFILES ) ), String( RTL_CONSTASCII_USTRINGPARAM( FILTERMASK_ALL ) ) );
478 xFltMgr->setCurrentFilter( String( RTL_CONSTASCII_USTRINGPARAM( "BASIC" ) ) );
479
480 if( xFP->execute() == RET_OK )
481 {
482 Sequence< ::rtl::OUString > aPaths = xFP->getFiles();
483 aCurPath = aPaths[0];
484 SfxMedium aMedium( aCurPath, STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE, sal_True );
485 SvStream* pStream = aMedium.GetInStream();
486 if ( pStream )
487 {
488 AssertValidEditEngine();
489 sal_uLong nLines = CalcLineCount( *pStream );
490 // nLines*4: ReadText/Formatting/Highlighting/Formatting
491 GetEditorWindow().CreateProgress( String( IDEResId( RID_STR_GENERATESOURCE ) ), nLines*4 );
492 GetEditEngine()->SetUpdateMode( sal_False );
493 GetEditView()->Read( *pStream );
494 GetEditEngine()->SetUpdateMode( sal_True );
495 GetEditorWindow().Update(); // Es wurde bei UpdateMode = sal_True nur Invalidiert
496 GetEditorWindow().ForceSyntaxTimeout();
497 GetEditorWindow().DestroyProgress();
498 sal_uLong nError = aMedium.GetError();
499 if ( nError )
500 ErrorHandler::HandleError( nError );
501 else
502 bDone = sal_True;
503 }
504 else
505 ErrorBox( this, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_COULDNTREAD ) ) ).Execute();
506 }
507 return bDone;
508 }
509
510
SaveBasicSource()511 sal_Bool ModulWindow::SaveBasicSource()
512 {
513 DBG_CHKTHIS( ModulWindow, 0 );
514 sal_Bool bDone = sal_False;
515
516 Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
517 Reference < XFilePicker > xFP;
518 if( xMSF.is() )
519 {
520 Sequence <Any> aServiceType(1);
521 aServiceType[0] <<= TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD;
522 xFP = Reference< XFilePicker >( xMSF->createInstanceWithArguments(
523 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ) ), aServiceType ), UNO_QUERY );
524 }
525
526 Reference< XFilePickerControlAccess > xFPControl(xFP, UNO_QUERY);
527 xFPControl->enableControl(ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, sal_False);
528 Any aValue;
529 aValue <<= (sal_Bool) sal_True;
530 xFPControl->setValue(ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue);
531
532 if ( aCurPath.Len() )
533 xFP->setDisplayDirectory ( aCurPath );
534
535 //xFP->setTitle( String( IDEResId( RID_STR_SAVE ) ) );
536
537 Reference< XFilterManager > xFltMgr(xFP, UNO_QUERY);
538 xFltMgr->appendFilter( String( RTL_CONSTASCII_USTRINGPARAM( "BASIC" ) ), String( RTL_CONSTASCII_USTRINGPARAM( "*.bas" ) ) );
539 xFltMgr->appendFilter( String( IDEResId( RID_STR_FILTER_ALLFILES ) ), String( RTL_CONSTASCII_USTRINGPARAM( FILTERMASK_ALL ) ) );
540 xFltMgr->setCurrentFilter( String( RTL_CONSTASCII_USTRINGPARAM( "BASIC" ) ) );
541
542 if( xFP->execute() == RET_OK )
543 {
544 Sequence< ::rtl::OUString > aPaths = xFP->getFiles();
545 aCurPath = aPaths[0];
546 SfxMedium aMedium( aCurPath, STREAM_WRITE | STREAM_SHARE_DENYWRITE | STREAM_TRUNC, sal_True, NULL );
547 SvStream* pStream = aMedium.GetOutStream();
548 if ( pStream )
549 {
550 EnterWait();
551 AssertValidEditEngine();
552 GetEditEngine()->Write( *pStream );
553 aMedium.Commit();
554 LeaveWait();
555 sal_uLong nError = aMedium.GetError();
556 if ( nError )
557 ErrorHandler::HandleError( nError );
558 else
559 bDone = sal_True;
560 }
561 else
562 ErrorBox( this, WB_OK | WB_DEF_OK, String( IDEResId( RID_STR_COULDNTWRITE) ) ).Execute();
563 }
564
565 return bDone;
566 }
567
568 sal_Bool implImportDialog( Window* pWin, const String& rCurPath, const ScriptDocument& rDocument, const String& aLibName );
569
ImportDialog()570 sal_Bool ModulWindow::ImportDialog()
571 {
572 const ScriptDocument& rDocument = GetDocument();
573 String aLibName = GetLibName();
574 sal_Bool bRet = implImportDialog( this, aCurPath, rDocument, aLibName );
575 return bRet;
576 }
577
ToggleBreakPoint(sal_uLong nLine)578 sal_Bool ModulWindow::ToggleBreakPoint( sal_uLong nLine )
579 {
580 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
581
582 sal_Bool bNewBreakPoint = sal_False;
583
584 if ( XModule().Is() )
585 {
586 CheckCompileBasic();
587 if ( aStatus.bError )
588 {
589 Sound::Beep();
590 return sal_False;
591 }
592
593 BreakPoint* pBrk = GetBreakPoints().FindBreakPoint( nLine );
594 if ( pBrk ) // entfernen
595 {
596 xModule->ClearBP( (sal_uInt16)nLine );
597 delete GetBreakPoints().Remove( pBrk );
598 }
599 else // einen erzeugen
600 {
601 if ( xModule->SetBP( (sal_uInt16)nLine) )
602 {
603 GetBreakPoints().InsertSorted( new BreakPoint( nLine ) );
604 bNewBreakPoint = sal_True;
605 if ( StarBASIC::IsRunning() )
606 {
607 for ( sal_uInt16 nMethod = 0; nMethod < xModule->GetMethods()->Count(); nMethod++ )
608 {
609 SbMethod* pMethod = (SbMethod*)xModule->GetMethods()->Get( nMethod );
610 DBG_ASSERT( pMethod, "Methode nicht gefunden! (NULL)" );
611 pMethod->SetDebugFlags( pMethod->GetDebugFlags() | SbDEBUG_BREAK );
612 }
613 }
614 }
615
616 if ( !bNewBreakPoint )
617 Sound::Beep();
618 }
619 }
620
621 return bNewBreakPoint;
622 }
623
UpdateBreakPoint(const BreakPoint & rBrk)624 void ModulWindow::UpdateBreakPoint( const BreakPoint& rBrk )
625 {
626 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
627
628 if ( XModule().Is() )
629 {
630 CheckCompileBasic();
631
632 if ( rBrk.bEnabled )
633 xModule->SetBP( (sal_uInt16)rBrk.nLine );
634 else
635 xModule->ClearBP( (sal_uInt16)rBrk.nLine );
636 }
637 }
638
639
BasicToggleBreakPoint()640 sal_Bool ModulWindow::BasicToggleBreakPoint()
641 {
642 DBG_CHKTHIS( ModulWindow, 0 );
643 AssertValidEditEngine();
644
645 TextSelection aSel = GetEditView()->GetSelection();
646 aSel.GetStart().GetPara()++; // Basic-Zeilen beginnen bei 1!
647 aSel.GetEnd().GetPara()++;
648
649 sal_Bool bNewBreakPoint = sal_False;
650
651 for ( sal_uLong nLine = aSel.GetStart().GetPara(); nLine <= aSel.GetEnd().GetPara(); nLine++ )
652 {
653 if ( ToggleBreakPoint( nLine ) )
654 bNewBreakPoint = sal_True;
655 }
656
657 aXEditorWindow.GetBrkWindow().Invalidate();
658 return bNewBreakPoint;
659 }
660
661
BasicToggleBreakPointEnabled()662 void ModulWindow::BasicToggleBreakPointEnabled()
663 {
664 DBG_CHKTHIS( ModulWindow, 0 );
665 AssertValidEditEngine();
666
667 ExtTextView* pView = GetEditView();
668 if ( pView )
669 {
670 TextSelection aSel = pView->GetSelection();
671 BreakPointList& rList = GetBreakPoints();
672
673 for ( sal_uLong nLine = ++aSel.GetStart().GetPara(), nEnd = ++aSel.GetEnd().GetPara(); nLine <= nEnd; ++nLine )
674 {
675 BreakPoint* pBrk = rList.FindBreakPoint( nLine );
676 if ( pBrk )
677 {
678 pBrk->bEnabled = pBrk->bEnabled ? sal_False : sal_True;
679 UpdateBreakPoint( *pBrk );
680 }
681 }
682
683 GetBreakPointWindow().Invalidate();
684 }
685 }
686
687
ManageBreakPoints()688 void ModulWindow::ManageBreakPoints()
689 {
690 BreakPointWindow& rBrkWin = GetBreakPointWindow();
691 BreakPointDialog aBrkDlg( &rBrkWin, GetBreakPoints() );
692 aBrkDlg.Execute();
693 rBrkWin.Invalidate();
694 }
695
696
IMPL_LINK(ModulWindow,BasicErrorHdl,StarBASIC *,pBasic)697 IMPL_LINK( ModulWindow, BasicErrorHdl, StarBASIC *, pBasic )
698 {
699 DBG_CHKTHIS( ModulWindow, 0 );
700 GoOnTop();
701
702 // ReturnWert: BOOL
703 // FALSE: Abbrechen
704 // TRUE: Weiter....
705 String aErrorText( pBasic->GetErrorText() );
706 sal_uInt16 nErrorLine = pBasic->GetLine() - 1;
707 sal_uInt16 nErrCol1 = pBasic->GetCol1();
708 sal_uInt16 nErrCol2 = pBasic->GetCol2();
709 if ( nErrCol2 != 0xFFFF )
710 nErrCol2++;
711
712 AssertValidEditEngine();
713 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine, nErrCol1 ), TextPaM( nErrorLine, nErrCol2 ) ) );
714
715 String aErrorTextPrefix;
716 if( pBasic->IsCompilerError() )
717 {
718 aErrorTextPrefix = String( IDEResId( RID_STR_COMPILEERROR ) );
719 }
720 else
721 {
722 aErrorTextPrefix = String( IDEResId( RID_STR_RUNTIMEERROR ) );
723 aErrorTextPrefix += StarBASIC::GetVBErrorCode( pBasic->GetErrorCode() );
724 aErrorTextPrefix += ' ';
725 pLayout->GetStackWindow().UpdateCalls();
726 }
727 // Wenn anderes Basic, dan sollte die IDE versuchen, da richtige
728 // Modul anzuzeigen...
729 sal_Bool bMarkError = ( pBasic == GetBasic() ) ? sal_True : sal_False;
730 if ( bMarkError )
731 aXEditorWindow.GetBrkWindow().SetMarkerPos( nErrorLine, sal_True );
732 // ErrorBox( this, WB_OK | WB_DEF_OK, String( aErrorTextPrefix + aErrorText ) ).Execute();
733 // ErrorHandler::HandleError( pBasic->GetErrorCode() );
734
735 // #i47002#
736 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( this );
737
738 ErrorHandler::HandleError( StarBASIC::GetErrorCode() );
739
740 // #i47002#
741 Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
742 if ( !pWindow )
743 return sal_False;
744
745 if ( bMarkError )
746 aXEditorWindow.GetBrkWindow().SetMarkerPos( MARKER_NOMARKER );
747 return sal_False;
748 }
749
BasicBreakHdl(StarBASIC * pBasic)750 long __EXPORT ModulWindow::BasicBreakHdl( StarBASIC* pBasic )
751 {
752 DBG_CHKTHIS( ModulWindow, 0 );
753 // Ein GoOnTop aktiviert da Fenster, das veraendert aber den Context fuer
754 // das Programm!
755 // GoOnTop();
756
757 // #i69280 Required in Window despite normal usage in next command!
758 (void)pBasic;
759
760 // ReturnWert: sal_uInt16 => siehe SB-Debug-Flags
761 sal_uInt16 nErrorLine = pBasic->GetLine();
762
763 // Gibt es hier einen BreakPoint?
764 BreakPoint* pBrk = GetBreakPoints().FindBreakPoint( nErrorLine );
765 if ( pBrk )
766 {
767 pBrk->nHitCount++;
768 if ( pBrk->nHitCount < pBrk->nStopAfter && GetBasic()->IsBreak() )
769 return aStatus.nBasicFlags; // weiterlaufen...
770 }
771
772 nErrorLine--; // EditEngine begint bei 0, Basic bei 1
773 // Alleine schon damit gescrollt wird...
774 AssertValidEditEngine();
775 GetEditView()->SetSelection( TextSelection( TextPaM( nErrorLine, 0 ), TextPaM( nErrorLine, 0 ) ) );
776 aXEditorWindow.GetBrkWindow().SetMarkerPos( nErrorLine );
777
778 pLayout->GetWatchWindow().UpdateWatches();
779 pLayout->GetStackWindow().UpdateCalls();
780
781 aStatus.bIsInReschedule = sal_True;
782 aStatus.bIsRunning = sal_True;
783
784 AddStatus( BASWIN_INRESCHEDULE );
785
786 BasicIDE::InvalidateDebuggerSlots();
787
788 while( aStatus.bIsRunning )
789 Application::Yield();
790
791 aStatus.bIsInReschedule = sal_False;
792 aXEditorWindow.GetBrkWindow().SetMarkerPos( MARKER_NOMARKER );
793
794 ClearStatus( BASWIN_INRESCHEDULE );
795
796 return aStatus.nBasicFlags;
797 }
798
BasicAddWatch()799 void ModulWindow::BasicAddWatch()
800 {
801 DBG_CHKTHIS( ModulWindow, 0 );
802 String aWatchStr;
803 sal_Bool bInserted = sal_False;
804 AssertValidEditEngine();
805 sal_Bool bAdd = sal_True;
806 if ( !GetEditView()->HasSelection() )
807 {
808 // bAdd = GetEditView()->SelectCurrentWord();
809 TextPaM aWordStart;
810 String aWord = GetEditEngine()->GetWord( GetEditView()->GetSelection().GetEnd(), &aWordStart );
811 if ( aWord.Len() )
812 {
813 TextSelection aSel( aWordStart );
814 sal_uInt16& rIndex = aSel.GetEnd().GetIndex();
815 rIndex = rIndex + aWord.Len();
816 // aSel.GetEnd().GetIndex() += sal::static_int_cast<int>( aWord.Len() );
817 GetEditView()->SetSelection( aSel );
818 bAdd = sal_True;
819 }
820 }
821 if ( bAdd )
822 {
823 TextSelection aSel = GetEditView()->GetSelection();
824 if ( aSel.GetStart().GetPara() == aSel.GetEnd().GetPara() )
825 {
826 aWatchStr = GetEditView()->GetSelected();
827 pLayout->GetWatchWindow().AddWatch( aWatchStr );
828 pLayout->GetWatchWindow().UpdateWatches();
829 bInserted = sal_True;
830 }
831 }
832
833 if ( !bInserted )
834 Sound::Beep();
835 }
836
837
838
BasicRemoveWatch()839 void ModulWindow::BasicRemoveWatch()
840 {
841 DBG_CHKTHIS( ModulWindow, 0 );
842 sal_Bool bRemoved = pLayout->GetWatchWindow().RemoveSelectedWatch();
843
844 if ( !bRemoved )
845 Sound::Beep();
846 }
847
848
EditMacro(const String & rMacroName)849 void ModulWindow::EditMacro( const String& rMacroName )
850 {
851 DBG_CHKTHIS( ModulWindow, 0 );
852 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
853
854 if ( XModule().Is() )
855 {
856 CheckCompileBasic();
857
858 if ( !aStatus.bError )
859 {
860 sal_uInt16 nStart, nEnd;
861 SbMethod* pMethod = (SbMethod*)xModule->Find( rMacroName, SbxCLASS_METHOD );
862 if ( pMethod )
863 {
864 pMethod->GetLineRange( nStart, nEnd );
865 if ( nStart )
866 {
867 // Basic beginnt bei 1
868 nStart--;
869 nEnd--;
870 }
871 TextSelection aSel( TextPaM( nStart, 0 ), TextPaM( nStart, 0 ) );
872 AssertValidEditEngine();
873 TextView * pView = GetEditView();
874 // ggf. hinscrollen, so dass erste Zeile oben...
875 long nVisHeight = GetOutputSizePixel().Height();
876 if ( (long)pView->GetTextEngine()->GetTextHeight() > nVisHeight )
877 {
878 long nMaxY = pView->GetTextEngine()->GetTextHeight() - nVisHeight;
879 long nOldStartY = pView->GetStartDocPos().Y();
880 long nNewStartY = nStart * pView->GetTextEngine()->GetCharHeight();
881 nNewStartY = Min( nNewStartY, nMaxY );
882 pView->Scroll( 0, -(nNewStartY-nOldStartY) );
883 pView->ShowCursor( sal_False, sal_True );
884 GetEditVScrollBar().SetThumbPos( pView->GetStartDocPos().Y() );
885 }
886 pView->SetSelection( aSel );
887 pView->ShowCursor();
888 pView->GetWindow()->GrabFocus();
889 }
890 }
891 }
892 }
893
894
StoreData()895 void __EXPORT ModulWindow::StoreData()
896 {
897 DBG_CHKTHIS( ModulWindow, 0 );
898 // StoreData wird gerufen, wenn der BasicManager zerstoert oder
899 // dieses Fenster beendet wird.
900 // => Keine Unterbrechungen erwuenscht!
901 // Und bei SAVE, wenn AppBasic...
902 GetEditorWindow().SetSourceInBasic( sal_True );
903 // Nicht das Modify loeschen, sonst wird das Basic nicht gespeichert
904 // Es wird beim Speichern sowieso geloescht.
905 // xModule->SetModified( sal_False );
906 }
907
CanClose()908 sal_Bool __EXPORT ModulWindow::CanClose()
909 {
910 DBG_CHKTHIS( ModulWindow, 0 );
911 return sal_True;
912 }
913
914
AllowUndo()915 sal_Bool __EXPORT ModulWindow::AllowUndo()
916 {
917 return GetEditorWindow().CanModify();
918 }
919
920
UpdateData()921 void __EXPORT ModulWindow::UpdateData()
922 {
923 DBG_CHKTHIS( ModulWindow, 0 );
924 DBG_ASSERT( XModule().Is(), "Kein Modul!" );
925 // UpdateData wird gerufen, wenn sich der Source von aussen
926 // geaendert hat.
927 // => Keine Unterbrechungen erwuenscht!
928
929 if ( XModule().Is() )
930 {
931 SetModule( xModule->GetSource32() );
932
933 if ( GetEditView() )
934 {
935 TextSelection aSel = GetEditView()->GetSelection();
936 setTextEngineText( GetEditEngine(), xModule->GetSource32() );
937 GetEditView()->SetSelection( aSel );
938 GetEditEngine()->SetModified( sal_False );
939 BasicIDE::MarkDocumentModified( GetDocument() );
940 }
941 }
942 }
943
countPages(Printer * pPrinter)944 sal_Int32 ModulWindow::countPages( Printer* pPrinter )
945 {
946 return FormatAndPrint( pPrinter, -1 );
947 }
948
printPage(sal_Int32 nPage,Printer * pPrinter)949 void ModulWindow::printPage( sal_Int32 nPage, Printer* pPrinter )
950 {
951 FormatAndPrint( pPrinter, nPage );
952 }
953
954 /* implementation note: this is totally inefficient for the XRenderable interface
955 usage since the whole "document" will be format for every page. Should this ever
956 become a problem we should
957 - format only once for every new printer
958 - keep an index list for each page which is the starting paragraph
959 */
FormatAndPrint(Printer * pPrinter,sal_Int32 nPrintPage)960 sal_Int32 ModulWindow::FormatAndPrint( Printer* pPrinter, sal_Int32 nPrintPage )
961 {
962 DBG_CHKTHIS( ModulWindow, 0 );
963
964 AssertValidEditEngine();
965
966 MapMode eOldMapMode( pPrinter->GetMapMode() );
967 Font aOldFont( pPrinter->GetFont() );
968
969 // Font aFont( GetEditEngine()->CreateFontFromItemSet( GetEditEngine()->GetEmptyItemSet() ) );
970 Font aFont( GetEditEngine()->GetFont() );
971 aFont.SetAlign( ALIGN_BOTTOM );
972 aFont.SetTransparent( sal_True );
973 aFont.SetSize( Size( 0, 360 ) );
974 pPrinter->SetFont( aFont );
975 pPrinter->SetMapMode( MAP_100TH_MM );
976
977 String aTitle( CreateQualifiedName() );
978
979 sal_uInt16 nLineHeight = (sal_uInt16) pPrinter->GetTextHeight(); // etwas mehr.
980 sal_uInt16 nParaSpace = 10;
981
982 Size aPaperSz = pPrinter->GetOutputSize();
983 aPaperSz.Width() -= (LMARGPRN+RMARGPRN);
984 aPaperSz.Height() -= (TMARGPRN+BMARGPRN);
985
986 // nLinepPage stimmt nicht, wenn Zeilen umgebrochen werden muessen...
987 sal_uInt16 nLinespPage = (sal_uInt16) (aPaperSz.Height()/nLineHeight);
988 sal_uInt16 nCharspLine = (sal_uInt16) (aPaperSz.Width() / pPrinter->GetTextWidth( 'X' ) );
989 sal_uLong nParas = GetEditEngine()->GetParagraphCount();
990
991 sal_uInt16 nPages = (sal_uInt16) (nParas/nLinespPage+1 );
992 sal_uInt16 nCurPage = 1;
993
994 // Header drucken...
995 lcl_PrintHeader( pPrinter, nPages, nCurPage, aTitle, nPrintPage == 0 );
996 Point aPos( LMARGPRN, TMARGPRN );
997 for ( sal_uLong nPara = 0; nPara < nParas; nPara++ )
998 {
999 String aLine( GetEditEngine()->GetText( nPara ) );
1000 lcl_ConvertTabsToSpaces( aLine );
1001 sal_uInt16 nLines = aLine.Len()/nCharspLine+1;
1002 for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
1003 {
1004 String aTmpLine( aLine, nLine*nCharspLine, nCharspLine );
1005 aPos.Y() += nLineHeight;
1006 if ( aPos.Y() > ( aPaperSz.Height()+TMARGPRN ) )
1007 {
1008 nCurPage++;
1009 lcl_PrintHeader( pPrinter, nPages, nCurPage, aTitle, nCurPage-1 == nPrintPage );
1010 aPos = Point( LMARGPRN, TMARGPRN+nLineHeight );
1011 }
1012 if( nCurPage-1 == nPrintPage )
1013 pPrinter->DrawText( aPos, aTmpLine );
1014 }
1015 aPos.Y() += nParaSpace;
1016 }
1017
1018 pPrinter->SetFont( aOldFont );
1019 pPrinter->SetMapMode( eOldMapMode );
1020
1021 return sal_Int32(nCurPage);
1022 }
1023
1024
ExecuteCommand(SfxRequest & rReq)1025 void __EXPORT ModulWindow::ExecuteCommand( SfxRequest& rReq )
1026 {
1027 DBG_CHKTHIS( ModulWindow, 0 );
1028 AssertValidEditEngine();
1029 sal_uInt16 nSlot = rReq.GetSlot();
1030 switch ( nSlot )
1031 {
1032 case SID_BASICRUN:
1033 {
1034 BasicRun();
1035 }
1036 break;
1037 case SID_BASICCOMPILE:
1038 {
1039 CompileBasic();
1040 }
1041 break;
1042 case SID_BASICSTEPOVER:
1043 {
1044 BasicStepOver();
1045 }
1046 break;
1047 case SID_BASICSTEPINTO:
1048 {
1049 BasicStepInto();
1050 }
1051 break;
1052 case SID_BASICSTEPOUT:
1053 {
1054 BasicStepOut();
1055 }
1056 break;
1057 case SID_BASICLOAD:
1058 {
1059 LoadBasic();
1060 }
1061 break;
1062 case SID_BASICSAVEAS:
1063 {
1064 SaveBasicSource();
1065 }
1066 break;
1067 case SID_IMPORT_DIALOG:
1068 {
1069 ImportDialog();
1070 }
1071 break;
1072 case SID_BASICIDE_MATCHGROUP:
1073 {
1074 if ( !GetEditView()->MatchGroup() )
1075 Sound::Beep();
1076 }
1077 break;
1078 case SID_BASICIDE_TOGGLEBRKPNT:
1079 {
1080 BasicToggleBreakPoint();
1081 }
1082 break;
1083 case SID_BASICIDE_MANAGEBRKPNTS:
1084 {
1085 ManageBreakPoints();
1086 }
1087 break;
1088 case SID_BASICIDE_TOGGLEBRKPNTENABLED:
1089 {
1090 BasicToggleBreakPointEnabled();
1091 }
1092 break;
1093 case SID_BASICIDE_ADDWATCH:
1094 {
1095 BasicAddWatch();
1096 }
1097 break;
1098 case SID_BASICIDE_REMOVEWATCH:
1099 {
1100 BasicRemoveWatch();
1101 }
1102 break;
1103 case SID_CUT:
1104 {
1105 if ( !IsReadOnly() )
1106 {
1107 GetEditView()->Cut();
1108 SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
1109 if ( pBindings )
1110 pBindings->Invalidate( SID_DOC_MODIFIED );
1111 }
1112 }
1113 break;
1114 case SID_COPY:
1115 {
1116 GetEditView()->Copy();
1117 }
1118 break;
1119 case SID_PASTE:
1120 {
1121 if ( !IsReadOnly() )
1122 {
1123 GetEditView()->Paste();
1124 SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
1125 if ( pBindings )
1126 pBindings->Invalidate( SID_DOC_MODIFIED );
1127 }
1128 }
1129 break;
1130 case SID_BASICIDE_BRKPNTSCHANGED:
1131 {
1132 GetBreakPointWindow().Invalidate();
1133 }
1134 break;
1135 case SID_SELECTALL:
1136 {
1137 TextSelection aSel( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, 0xFFFF ) );
1138 TextView * pView = GetEditView();
1139 pView->SetSelection( aSel );
1140 pView->GetWindow()->GrabFocus();
1141 }
1142 break;
1143 }
1144 }
1145
1146
1147
GetState(SfxItemSet & rSet)1148 void __EXPORT ModulWindow::GetState( SfxItemSet &rSet )
1149 {
1150 DBG_CHKTHIS( ModulWindow, 0 );
1151 SfxWhichIter aIter(rSet);
1152 for ( sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich() )
1153 {
1154 switch ( nWh )
1155 {
1156 // allgemeine Items:
1157 case SID_CUT:
1158 {
1159 if ( !GetEditView() || !GetEditView()->HasSelection() )
1160 rSet.DisableItem( nWh );
1161
1162 if ( IsReadOnly() )
1163 rSet.DisableItem( nWh );
1164 }
1165 break;
1166 case SID_COPY:
1167 {
1168 if ( !GetEditView() || !GetEditView()->HasSelection() )
1169 rSet.DisableItem( nWh );
1170 }
1171 break;
1172 case SID_PASTE:
1173 {
1174 if ( !IsPasteAllowed() )
1175 rSet.DisableItem( nWh );
1176
1177 if ( IsReadOnly() )
1178 rSet.DisableItem( nWh );
1179 }
1180 break;
1181 case SID_BASICIDE_STAT_POS:
1182 {
1183 TextView* pView = GetEditView();
1184 if ( pView )
1185 {
1186 TextSelection aSel = pView->GetSelection();
1187 String aPos( IDEResId( RID_STR_LINE ) );
1188 aPos += ' ';
1189 aPos += String::CreateFromInt32( aSel.GetEnd().GetPara()+1 );
1190 aPos += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) );
1191 aPos += String( IDEResId( RID_STR_COLUMN ) );
1192 aPos += ' ';
1193 aPos += String::CreateFromInt32( aSel.GetEnd().GetIndex()+1 );
1194 SfxStringItem aItem( SID_BASICIDE_STAT_POS, aPos );
1195 rSet.Put( aItem );
1196 }
1197 }
1198 break;
1199 case SID_ATTR_INSERT:
1200 {
1201 TextView* pView = GetEditView();
1202 if ( pView )
1203 {
1204 SfxBoolItem aItem( SID_ATTR_INSERT, pView->IsInsertMode() );
1205 rSet.Put( aItem );
1206 }
1207 }
1208 break;
1209 case SID_SELECTALL:
1210 {
1211 if ( !GetEditView() )
1212 rSet.DisableItem( nWh );
1213 }
1214 break;
1215 }
1216 }
1217 }
1218
1219
DoScroll(ScrollBar * pCurScrollBar)1220 void __EXPORT ModulWindow::DoScroll( ScrollBar* pCurScrollBar )
1221 {
1222 DBG_CHKTHIS( ModulWindow, 0 );
1223 if ( ( pCurScrollBar == GetHScrollBar() ) && GetEditView() )
1224 {
1225 // Nicht mit dem Wert Scrollen, sondern lieber die Thumb-Pos fuer die
1226 // VisArea verwenden:
1227 long nDiff = GetEditView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
1228 GetEditView()->Scroll( nDiff, 0 );
1229 GetEditView()->ShowCursor( sal_False, sal_True );
1230 pCurScrollBar->SetThumbPos( GetEditView()->GetStartDocPos().X() );
1231
1232 }
1233 }
1234
1235
IsModified()1236 sal_Bool __EXPORT ModulWindow::IsModified()
1237 {
1238 return GetEditEngine() ? GetEditEngine()->IsModified() : sal_False;
1239 }
1240
1241
1242
GoOnTop()1243 void __EXPORT ModulWindow::GoOnTop()
1244 {
1245 IDE_DLL()->GetShell()->GetViewFrame()->ToTop();
1246 }
1247
GetSbModuleName()1248 String ModulWindow::GetSbModuleName()
1249 {
1250 String aModuleName;
1251 if ( XModule().Is() )
1252 aModuleName = xModule->GetName();
1253 return aModuleName;
1254 }
1255
1256
1257
GetTitle()1258 String __EXPORT ModulWindow::GetTitle()
1259 {
1260 return GetSbModuleName();
1261 }
1262
1263
1264
FrameWindowMoved()1265 void ModulWindow::FrameWindowMoved()
1266 {
1267 // if ( GetEditEngine() && GetEditEngine()->IsInSelectionMode() )
1268 // GetEditEngine()->StopSelectionMode();
1269 }
1270
1271
1272
ShowCursor(sal_Bool bOn)1273 void ModulWindow::ShowCursor( sal_Bool bOn )
1274 {
1275 if ( GetEditEngine() )
1276 {
1277 TextView* pView = GetEditEngine()->GetActiveView();
1278 if ( pView )
1279 {
1280 if ( bOn )
1281 pView->ShowCursor();
1282 else
1283 pView->HideCursor();
1284 }
1285 }
1286 }
1287
1288
GetLayoutWindow()1289 Window* __EXPORT ModulWindow::GetLayoutWindow()
1290 {
1291 return pLayout;
1292 }
1293
AssertValidEditEngine()1294 void ModulWindow::AssertValidEditEngine()
1295 {
1296 if ( !GetEditEngine() )
1297 GetEditorWindow().CreateEditEngine();
1298 }
1299
Deactivating()1300 void ModulWindow::Deactivating()
1301 {
1302 if ( GetEditView() )
1303 GetEditView()->EraseVirtualDevice();
1304 }
1305
StartSearchAndReplace(const SvxSearchItem & rSearchItem,sal_Bool bFromStart)1306 sal_uInt16 ModulWindow::StartSearchAndReplace( const SvxSearchItem& rSearchItem, sal_Bool bFromStart )
1307 {
1308 // Mann koennte fuer das blinde Alle-Ersetzen auch auf
1309 // Syntaxhighlighting/Formatierung verzichten...
1310 AssertValidEditEngine();
1311 ExtTextView* pView = GetEditView();
1312 TextSelection aSel;
1313 if ( bFromStart )
1314 {
1315 aSel = pView->GetSelection();
1316 if ( !rSearchItem.GetBackward() )
1317 pView->SetSelection( TextSelection() );
1318 else
1319 pView->SetSelection( TextSelection( TextPaM( 0xFFFFFFFF, 0xFFFF ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
1320 }
1321
1322 sal_Bool bForward = !rSearchItem.GetBackward();
1323 sal_uInt16 nFound = 0;
1324 if ( ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND ) ||
1325 ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL ) )
1326 {
1327 nFound = pView->Search( rSearchItem.GetSearchOptions() , bForward );
1328 }
1329 else if ( ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE ) ||
1330 ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL ) )
1331 {
1332 if ( !IsReadOnly() )
1333 {
1334 sal_Bool bAll = rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL;
1335 nFound = pView->Replace( rSearchItem.GetSearchOptions() , bAll , bForward );
1336 }
1337 }
1338
1339 if ( bFromStart && !nFound )
1340 pView->SetSelection( aSel );
1341
1342 return nFound;
1343 }
1344
GetUndoManager()1345 ::svl::IUndoManager* __EXPORT ModulWindow::GetUndoManager()
1346 {
1347 if ( GetEditEngine() )
1348 return &GetEditEngine()->GetUndoManager();
1349 return NULL;
1350 }
1351
GetSearchOptions()1352 sal_uInt16 __EXPORT ModulWindow::GetSearchOptions()
1353 {
1354 sal_uInt16 nOptions = SEARCH_OPTIONS_SEARCH |
1355 SEARCH_OPTIONS_WHOLE_WORDS |
1356 SEARCH_OPTIONS_BACKWARDS |
1357 SEARCH_OPTIONS_REG_EXP |
1358 SEARCH_OPTIONS_EXACT |
1359 SEARCH_OPTIONS_SELECTION |
1360 SEARCH_OPTIONS_SIMILARITY;
1361
1362 if ( !IsReadOnly() )
1363 {
1364 nOptions |= SEARCH_OPTIONS_REPLACE;
1365 nOptions |= SEARCH_OPTIONS_REPLACE_ALL;
1366 }
1367
1368 return nOptions;
1369 }
1370
BasicStarted()1371 void __EXPORT ModulWindow::BasicStarted()
1372 {
1373 if ( XModule().Is() )
1374 {
1375 aStatus.bIsRunning = sal_True;
1376 BreakPointList& rList = GetBreakPoints();
1377 if ( rList.Count() )
1378 {
1379 rList.ResetHitCount();
1380 rList.SetBreakPointsInBasic( xModule );
1381 for ( sal_uInt16 nMethod = 0; nMethod < xModule->GetMethods()->Count(); nMethod++ )
1382 {
1383 SbMethod* pMethod = (SbMethod*)xModule->GetMethods()->Get( nMethod );
1384 DBG_ASSERT( pMethod, "Methode nicht gefunden! (NULL)" );
1385 pMethod->SetDebugFlags( pMethod->GetDebugFlags() | SbDEBUG_BREAK );
1386 }
1387 }
1388 }
1389 }
1390
BasicStopped()1391 void __EXPORT ModulWindow::BasicStopped()
1392 {
1393 aStatus.bIsRunning = sal_False;
1394 GetBreakPointWindow().SetMarkerPos( MARKER_NOMARKER );
1395 }
1396
CreateEntryDescriptor()1397 BasicEntryDescriptor ModulWindow::CreateEntryDescriptor()
1398 {
1399 ScriptDocument aDocument( GetDocument() );
1400 String aLibName( GetLibName() );
1401 LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName );
1402 String aModName( GetName() );
1403 String aLibSubName;
1404 if( xBasic.Is() && aDocument.isInVBAMode() && XModule().Is() )
1405 {
1406 switch( xModule->GetModuleType() )
1407 {
1408 case script::ModuleType::DOCUMENT:
1409 {
1410 aLibSubName = String( IDEResId( RID_STR_DOCUMENT_OBJECTS ) );
1411 uno::Reference< container::XNameContainer > xLib = aDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
1412 if( xLib.is() )
1413 {
1414 String sObjName;
1415 ModuleInfoHelper::getObjectName( xLib, aModName, sObjName );
1416 if( sObjName.Len() )
1417 {
1418 aModName.AppendAscii(" (").Append(sObjName).AppendAscii(")");
1419 }
1420 }
1421 break;
1422 }
1423 case script::ModuleType::FORM:
1424 aLibSubName = String( IDEResId( RID_STR_USERFORMS ) );
1425 break;
1426 case script::ModuleType::NORMAL:
1427 aLibSubName = String( IDEResId( RID_STR_NORMAL_MODULES ) );
1428 break;
1429 case script::ModuleType::CLASS:
1430 aLibSubName = String( IDEResId( RID_STR_CLASS_MODULES ) );
1431 break;
1432 }
1433 }
1434 return BasicEntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aModName, OBJ_TYPE_MODULE );
1435 }
1436
SetReadOnly(sal_Bool b)1437 void ModulWindow::SetReadOnly( sal_Bool b )
1438 {
1439 if ( GetEditView() )
1440 GetEditView()->SetReadOnly( b );
1441 }
1442
IsReadOnly()1443 sal_Bool ModulWindow::IsReadOnly()
1444 {
1445 sal_Bool bReadOnly = sal_False;
1446
1447 if ( GetEditView() )
1448 bReadOnly = GetEditView()->IsReadOnly();
1449
1450 return bReadOnly;
1451 }
1452
IsPasteAllowed()1453 sal_Bool ModulWindow::IsPasteAllowed()
1454 {
1455 sal_Bool bPaste = sal_False;
1456
1457 // get clipboard
1458 Reference< datatransfer::clipboard::XClipboard > xClipboard = GetClipboard();
1459 if ( xClipboard.is() )
1460 {
1461 // get clipboard content
1462 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1463 Reference< datatransfer::XTransferable > xTransf = xClipboard->getContents();
1464 Application::AcquireSolarMutex( nRef );
1465 if ( xTransf.is() )
1466 {
1467 datatransfer::DataFlavor aFlavor;
1468 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
1469 if ( xTransf->isDataFlavorSupported( aFlavor ) )
1470 {
1471 bPaste = sal_True;
1472 }
1473 }
1474 }
1475
1476 return bPaste;
1477 }
1478
ModulWindowLayout(Window * pParent)1479 ModulWindowLayout::ModulWindowLayout( Window* pParent ) :
1480 Window( pParent, WB_CLIPCHILDREN ),
1481 aVSplitter( this, WinBits( WB_VSCROLL ) ),
1482 aHSplitter( this, WinBits( WB_HSCROLL ) ),
1483 aWatchWindow( this ),
1484 aStackWindow( this ),
1485 bVSplitted(sal_False),
1486 bHSplitted(sal_False),
1487 m_pModulWindow(0),
1488 m_aImagesNormal(IDEResId(RID_IMGLST_LAYOUT)),
1489 m_aImagesHighContrast(IDEResId(RID_IMGLST_LAYOUT_HC))
1490 {
1491 SetBackground(GetSettings().GetStyleSettings().GetWindowColor());
1492
1493 aVSplitter.SetSplitHdl( LINK( this, ModulWindowLayout, SplitHdl ) );
1494 aHSplitter.SetSplitHdl( LINK( this, ModulWindowLayout, SplitHdl ) );
1495 aVSplitter.Show();
1496 aHSplitter.Show();
1497
1498 aWatchWindow.Show();
1499 aStackWindow.Show();
1500
1501 Color aColor(GetSettings().GetStyleSettings().GetFieldTextColor());
1502 m_aSyntaxColors[TT_UNKNOWN] = aColor;
1503 m_aSyntaxColors[TT_WHITESPACE] = aColor;
1504 m_aSyntaxColors[TT_EOL] = aColor;
1505 m_aColorConfig.AddListener(this);
1506 m_aSyntaxColors[TT_IDENTIFIER]
1507 = Color(m_aColorConfig.GetColorValue(svtools::BASICIDENTIFIER).nColor);
1508 m_aSyntaxColors[TT_NUMBER]
1509 = Color(m_aColorConfig.GetColorValue(svtools::BASICNUMBER).nColor);
1510 m_aSyntaxColors[TT_STRING]
1511 = Color(m_aColorConfig.GetColorValue(svtools::BASICSTRING).nColor);
1512 m_aSyntaxColors[TT_COMMENT]
1513 = Color(m_aColorConfig.GetColorValue(svtools::BASICCOMMENT).nColor);
1514 m_aSyntaxColors[TT_ERROR]
1515 = Color(m_aColorConfig.GetColorValue(svtools::BASICERROR).nColor);
1516 m_aSyntaxColors[TT_OPERATOR]
1517 = Color(m_aColorConfig.GetColorValue(svtools::BASICOPERATOR).nColor);
1518 m_aSyntaxColors[TT_KEYWORDS]
1519 = Color(m_aColorConfig.GetColorValue(svtools::BASICKEYWORD).nColor);
1520
1521 Font aFont( GetFont() );
1522 Size aSz( aFont.GetSize() );
1523 aSz.Height() *= 3;
1524 aSz.Height() /= 2;
1525 aFont.SetSize( aSz );
1526 aFont.SetWeight( WEIGHT_BOLD );
1527 aFont.SetColor(GetSettings().GetStyleSettings().GetWindowTextColor());
1528 SetFont( aFont );
1529 }
1530
~ModulWindowLayout()1531 ModulWindowLayout::~ModulWindowLayout()
1532 {
1533 m_aColorConfig.RemoveListener(this);
1534 }
1535
Resize()1536 void __EXPORT ModulWindowLayout::Resize()
1537 {
1538 // ScrollBars, etc. passiert in BasicIDEShell:Adjust...
1539 ArrangeWindows();
1540 // Invalidate();
1541 }
1542
Paint(const Rectangle &)1543 void __EXPORT ModulWindowLayout::Paint( const Rectangle& )
1544 {
1545 DrawText( Point(), String( IDEResId( RID_STR_NOMODULE ) ) );
1546 }
1547
1548
ArrangeWindows()1549 void ModulWindowLayout::ArrangeWindows()
1550 {
1551 Size aSz = GetOutputSizePixel();
1552
1553 // prueffen, ob der Splitter in einem gueltigen Bereich liegt...
1554 long nMinPos = SPLIT_MARGIN;
1555 long nMaxPos = aSz.Height() - SPLIT_MARGIN;
1556
1557 long nVSplitPos = aVSplitter.GetSplitPosPixel();
1558 long nHSplitPos = aHSplitter.GetSplitPosPixel();
1559 if ( !bVSplitted )
1560 {
1561 // Wenn noch nie gesplitted wurde, Verhaeltniss = 3 : 4
1562 nVSplitPos = aSz.Height() * 3 / 4;
1563 aVSplitter.SetSplitPosPixel( nVSplitPos );
1564 }
1565 if ( !bHSplitted )
1566 {
1567 // Wenn noch nie gesplitted wurde, Verhaeltniss = 2 : 3
1568 nHSplitPos = aSz.Width() * 2 / 3;
1569 aHSplitter.SetSplitPosPixel( nHSplitPos );
1570 }
1571 if ( ( nVSplitPos < nMinPos ) || ( nVSplitPos > nMaxPos ) )
1572 nVSplitPos = ( nVSplitPos < nMinPos ) ? 0 : ( aSz.Height() - SPLIT_HEIGHT );
1573
1574 Size aXEWSz;
1575 aXEWSz.Width() = aSz.Width();
1576 aXEWSz.Height() = nVSplitPos + 1;
1577 if ( m_pModulWindow )
1578 {
1579 DBG_CHKOBJ( m_pModulWindow, ModulWindow, 0 );
1580 m_pModulWindow->SetPosSizePixel( Point( 0, 0 ), aXEWSz );
1581 }
1582
1583 aVSplitter.SetDragRectPixel( Rectangle( Point( 0, 0 ), Size( aSz.Width(), aSz.Height() ) ) );
1584 aVSplitter.SetPosPixel( Point( 0, nVSplitPos ) );
1585 aVSplitter.SetSizePixel( Size( aSz.Width(), SPLIT_HEIGHT ) );
1586
1587 aHSplitter.SetDragRectPixel( Rectangle( Point( 0, nVSplitPos+SPLIT_HEIGHT ), Size( aSz.Width(), aSz.Height() - nVSplitPos - SPLIT_HEIGHT ) ) );
1588 aHSplitter.SetPosPixel( Point( nHSplitPos, nVSplitPos ) );
1589 aHSplitter.SetSizePixel( Size( SPLIT_HEIGHT, aSz.Height() - nVSplitPos ) );
1590
1591 Size aWWSz;
1592 Point aWWPos( 0, nVSplitPos+SPLIT_HEIGHT );
1593 aWWSz.Width() = nHSplitPos;
1594 aWWSz.Height() = aSz.Height() - aWWPos.Y();
1595 if ( !aWatchWindow.IsFloatingMode() )
1596 aWatchWindow.SetPosSizePixel( aWWPos, aWWSz );
1597
1598 Size aSWSz;
1599 Point aSWPos( nHSplitPos+SPLIT_HEIGHT, nVSplitPos+SPLIT_HEIGHT );
1600 aSWSz.Width() = aSz.Width() - aSWPos.X();
1601 aSWSz.Height() = aSz.Height() - aSWPos.Y();
1602 if ( !aStackWindow.IsFloatingMode() )
1603 aStackWindow.SetPosSizePixel( aSWPos, aSWSz );
1604
1605 if ( aStackWindow.IsFloatingMode() && aWatchWindow.IsFloatingMode() )
1606 aHSplitter.Hide();
1607 else
1608 aHSplitter.Show();
1609
1610 long nHDoubleClickSplitPosX = aSz.Width()-aHSplitter.GetSizePixel().Width();
1611 if ( aHSplitter.GetSplitPosPixel() < nHDoubleClickSplitPosX )
1612 aHSplitter.SetLastSplitPosPixel( nHDoubleClickSplitPosX );
1613
1614
1615 long nHDoubleClickSplitPosY = aSz.Height()-aVSplitter.GetSizePixel().Height();
1616 if ( aVSplitter.GetSplitPosPixel() < nHDoubleClickSplitPosY )
1617 aVSplitter.SetLastSplitPosPixel( nHDoubleClickSplitPosY );
1618 }
1619
IMPL_LINK(ModulWindowLayout,SplitHdl,Splitter *,pSplitter)1620 IMPL_LINK( ModulWindowLayout, SplitHdl, Splitter *, pSplitter )
1621 {
1622 if ( pSplitter == &aVSplitter )
1623 bVSplitted = sal_True;
1624 else
1625 bHSplitted = sal_True;
1626
1627 ArrangeWindows();
1628 return 0;
1629 }
1630
IsToBeDocked(DockingWindow * pDockingWindow,const Point & rPos,Rectangle & rRect)1631 sal_Bool ModulWindowLayout::IsToBeDocked( DockingWindow* pDockingWindow, const Point& rPos, Rectangle& rRect )
1632 {
1633 // prueffen, ob als Dock oder als Child:
1634 // TRUE: Floating
1635 // FALSE: Child
1636 Point aPosInMe = ScreenToOutputPixel( rPos );
1637 Size aSz = GetOutputSizePixel();
1638 if ( ( aPosInMe.X() > 0 ) && ( aPosInMe.X() < aSz.Width() ) &&
1639 ( aPosInMe.Y() > 0 ) && ( aPosInMe.Y() < aSz.Height() ) )
1640 {
1641 long nVSplitPos = aVSplitter.GetSplitPosPixel();
1642 long nHSplitPos = aHSplitter.GetSplitPosPixel();
1643 if ( pDockingWindow == &aWatchWindow )
1644 {
1645 if ( ( aPosInMe.Y() > nVSplitPos ) && ( aPosInMe.X() < nHSplitPos ) )
1646 {
1647 rRect.SetSize( Size( nHSplitPos, aSz.Height() - nVSplitPos ) );
1648 rRect.SetPos( OutputToScreenPixel( Point( 0, nVSplitPos ) ) );
1649 return sal_True;
1650 }
1651 }
1652 if ( pDockingWindow == &aStackWindow )
1653 {
1654 if ( ( aPosInMe.Y() > nVSplitPos ) && ( aPosInMe.X() > nHSplitPos ) )
1655 {
1656 rRect.SetSize( Size( aSz.Width() - nHSplitPos, aSz.Height() - nVSplitPos ) );
1657 rRect.SetPos( OutputToScreenPixel( Point( nHSplitPos, nVSplitPos ) ) );
1658 return sal_True;
1659 }
1660 }
1661 }
1662 return sal_False;
1663 }
1664
DockaWindow(DockingWindow * pDockingWindow)1665 void ModulWindowLayout::DockaWindow( DockingWindow* pDockingWindow )
1666 {
1667 if ( pDockingWindow == &aWatchWindow )
1668 {
1669 // evtl. Sonderbehandlung...
1670 ArrangeWindows();
1671 }
1672 else if ( pDockingWindow == &aStackWindow )
1673 {
1674 // evtl. Sonderbehandlung...
1675 ArrangeWindows();
1676 }
1677 #ifdef DBG_UTIL
1678 else
1679 DBG_ERROR( "Wer will sich denn hier andocken ?" );
1680 #endif
1681 }
1682
SetModulWindow(ModulWindow * pModWin)1683 void ModulWindowLayout::SetModulWindow( ModulWindow* pModWin )
1684 {
1685 m_pModulWindow = pModWin;
1686 ArrangeWindows();
1687 }
1688
1689 // virtual
DataChanged(DataChangedEvent const & rDCEvt)1690 void ModulWindowLayout::DataChanged(DataChangedEvent const & rDCEvt)
1691 {
1692 Window::DataChanged(rDCEvt);
1693 if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1694 && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1695 {
1696 bool bInvalidate = false;
1697 Color aColor(GetSettings().GetStyleSettings().GetWindowColor());
1698 if (aColor
1699 != rDCEvt.GetOldSettings()->GetStyleSettings().GetWindowColor())
1700 {
1701 SetBackground(Wallpaper(aColor));
1702 bInvalidate = true;
1703 }
1704 aColor = GetSettings().GetStyleSettings().GetWindowTextColor();
1705 if (aColor != rDCEvt.GetOldSettings()->
1706 GetStyleSettings().GetWindowTextColor())
1707 {
1708 Font aFont(GetFont());
1709 aFont.SetColor(aColor);
1710 SetFont(aFont);
1711 bInvalidate = true;
1712 }
1713 if (bInvalidate)
1714 Invalidate();
1715 aColor = GetSettings().GetStyleSettings().GetFieldTextColor();
1716 if (aColor != m_aSyntaxColors[TT_UNKNOWN])
1717 {
1718 m_aSyntaxColors[TT_UNKNOWN] = aColor;
1719 m_aSyntaxColors[TT_WHITESPACE] = aColor;
1720 m_aSyntaxColors[TT_EOL] = aColor;
1721 updateSyntaxHighlighting();
1722 }
1723 }
1724 }
1725
1726 // virtual
ConfigurationChanged(utl::ConfigurationBroadcaster *,sal_uInt32)1727 void ModulWindowLayout::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
1728 {
1729 {
1730 Color aColor(m_aColorConfig.GetColorValue(svtools::BASICIDENTIFIER).
1731 nColor);
1732 bool bChanged = aColor != m_aSyntaxColors[TT_IDENTIFIER];
1733 m_aSyntaxColors[TT_IDENTIFIER] = aColor;
1734 aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICNUMBER).nColor);
1735 if (bChanged || aColor != m_aSyntaxColors[TT_NUMBER])
1736 bChanged = true;
1737 m_aSyntaxColors[TT_NUMBER] = aColor;
1738 aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICSTRING).nColor);
1739 if (bChanged || aColor != m_aSyntaxColors[TT_STRING])
1740 bChanged = true;
1741 m_aSyntaxColors[TT_STRING] = aColor;
1742 aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICCOMMENT).
1743 nColor);
1744 if (bChanged || aColor != m_aSyntaxColors[TT_COMMENT])
1745 bChanged = true;
1746 m_aSyntaxColors[TT_COMMENT] = aColor;
1747 aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICERROR).nColor);
1748 if (bChanged || aColor != m_aSyntaxColors[TT_ERROR])
1749 bChanged = true;
1750 m_aSyntaxColors[TT_ERROR] = aColor;
1751 aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICOPERATOR).
1752 nColor);
1753 if (bChanged || aColor != m_aSyntaxColors[TT_OPERATOR])
1754 bChanged = true;
1755 m_aSyntaxColors[TT_OPERATOR] = aColor;
1756 aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICKEYWORD).
1757 nColor);
1758 if (bChanged || aColor != m_aSyntaxColors[TT_KEYWORDS])
1759 bChanged = true;
1760 m_aSyntaxColors[TT_KEYWORDS] = aColor;
1761 if (bChanged)
1762 updateSyntaxHighlighting();
1763 }
1764 }
1765
updateSyntaxHighlighting()1766 void ModulWindowLayout::updateSyntaxHighlighting()
1767 {
1768 if (m_pModulWindow != 0)
1769 {
1770 EditorWindow & rEditor = m_pModulWindow->GetEditorWindow();
1771 sal_uLong nCount = rEditor.GetEditEngine()->GetParagraphCount();
1772 for (sal_uLong i = 0; i < nCount; ++i)
1773 rEditor.DoDelayedSyntaxHighlight(i);
1774 }
1775 }
1776
getImage(sal_uInt16 nId,bool bHighContrastMode) const1777 Image ModulWindowLayout::getImage(sal_uInt16 nId, bool bHighContrastMode) const
1778 {
1779 return (bHighContrastMode ? m_aImagesHighContrast : m_aImagesNormal).
1780 GetImage(nId);
1781 }
1782