xref: /AOO41X/main/basctl/source/basicide/baside2.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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 
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 
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 
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 
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 
231 __EXPORT ModulWindow::~ModulWindow()
232 {
233     DBG_DTOR( ModulWindow, 0 );
234     nValid = 0;
235 
236     StarBASIC::Stop();
237 }
238 
239 
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 
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 
262 void __EXPORT ModulWindow::Paint( const Rectangle& )
263 {
264 }
265 
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 
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 
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() ).getLength() > 0 ) ? 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 
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 
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 
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 
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 
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 
447 void ModulWindow::BasicStop()
448 {
449     DBG_CHKTHIS( ModulWindow, 0 );
450 
451     GetBasic()->Stop();
452     aStatus.bIsRunning = sal_False;
453 }
454 
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 
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, sal_False );
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 
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 
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 
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 
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 
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 
688 void ModulWindow::ManageBreakPoints()
689 {
690     BreakPointWindow& rBrkWin = GetBreakPointWindow();
691     BreakPointDialog aBrkDlg( &rBrkWin, GetBreakPoints() );
692     aBrkDlg.Execute();
693     rBrkWin.Invalidate();
694 }
695 
696 
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 
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 
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 
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 
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 
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 
908 sal_Bool __EXPORT ModulWindow::CanClose()
909 {
910     DBG_CHKTHIS( ModulWindow, 0 );
911     return sal_True;
912 }
913 
914 
915 sal_Bool __EXPORT ModulWindow::AllowUndo()
916 {
917     return GetEditorWindow().CanModify();
918 }
919 
920 
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 
944 sal_Int32 ModulWindow::countPages( Printer* pPrinter )
945 {
946     return FormatAndPrint( pPrinter, -1 );
947 }
948 
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 */
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 
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     }
1136 }
1137 
1138 
1139 
1140 void __EXPORT ModulWindow::GetState( SfxItemSet &rSet )
1141 {
1142     DBG_CHKTHIS( ModulWindow, 0 );
1143     SfxWhichIter aIter(rSet);
1144     for ( sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich() )
1145     {
1146         switch ( nWh )
1147         {
1148             // allgemeine Items:
1149             case SID_CUT:
1150             {
1151                 if ( !GetEditView() || !GetEditView()->HasSelection() )
1152                     rSet.DisableItem( nWh );
1153 
1154                 if ( IsReadOnly() )
1155                     rSet.DisableItem( nWh );
1156             }
1157             break;
1158             case SID_COPY:
1159             {
1160                 if ( !GetEditView() || !GetEditView()->HasSelection() )
1161                     rSet.DisableItem( nWh );
1162             }
1163             break;
1164             case SID_PASTE:
1165             {
1166                 if ( !IsPasteAllowed() )
1167                     rSet.DisableItem( nWh );
1168 
1169                 if ( IsReadOnly() )
1170                     rSet.DisableItem( nWh );
1171             }
1172             break;
1173             case SID_BASICIDE_STAT_POS:
1174             {
1175                 TextView* pView = GetEditView();
1176                 if ( pView )
1177                 {
1178                     TextSelection aSel = pView->GetSelection();
1179                     String aPos( IDEResId( RID_STR_LINE ) );
1180                     aPos += ' ';
1181                     aPos += String::CreateFromInt32( aSel.GetEnd().GetPara()+1 );
1182                     aPos += String( RTL_CONSTASCII_USTRINGPARAM( ", " ) );
1183                     aPos += String( IDEResId( RID_STR_COLUMN ) );
1184                     aPos += ' ';
1185                     aPos += String::CreateFromInt32( aSel.GetEnd().GetIndex()+1 );
1186                     SfxStringItem aItem( SID_BASICIDE_STAT_POS, aPos );
1187                     rSet.Put( aItem );
1188                 }
1189             }
1190             break;
1191             case SID_ATTR_INSERT:
1192             {
1193                 TextView* pView = GetEditView();
1194                 if ( pView )
1195                 {
1196                     SfxBoolItem aItem( SID_ATTR_INSERT, pView->IsInsertMode() );
1197                     rSet.Put( aItem );
1198                 }
1199             }
1200             break;
1201         }
1202     }
1203 }
1204 
1205 
1206 void __EXPORT ModulWindow::DoScroll( ScrollBar* pCurScrollBar )
1207 {
1208     DBG_CHKTHIS( ModulWindow, 0 );
1209     if ( ( pCurScrollBar == GetHScrollBar() ) && GetEditView() )
1210     {
1211         // Nicht mit dem Wert Scrollen, sondern lieber die Thumb-Pos fuer die
1212         // VisArea verwenden:
1213         long nDiff = GetEditView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
1214         GetEditView()->Scroll( nDiff, 0 );
1215         GetEditView()->ShowCursor( sal_False, sal_True );
1216         pCurScrollBar->SetThumbPos( GetEditView()->GetStartDocPos().X() );
1217 
1218     }
1219 }
1220 
1221 
1222 sal_Bool __EXPORT ModulWindow::IsModified()
1223 {
1224     return GetEditEngine() ? GetEditEngine()->IsModified() : sal_False;
1225 }
1226 
1227 
1228 
1229 void __EXPORT ModulWindow::GoOnTop()
1230 {
1231     IDE_DLL()->GetShell()->GetViewFrame()->ToTop();
1232 }
1233 
1234 String ModulWindow::GetSbModuleName()
1235 {
1236     String aModuleName;
1237     if ( XModule().Is() )
1238         aModuleName = xModule->GetName();
1239     return aModuleName;
1240 }
1241 
1242 
1243 
1244 String __EXPORT ModulWindow::GetTitle()
1245 {
1246     return GetSbModuleName();
1247 }
1248 
1249 
1250 
1251 void ModulWindow::FrameWindowMoved()
1252 {
1253 //  if ( GetEditEngine() && GetEditEngine()->IsInSelectionMode() )
1254 //      GetEditEngine()->StopSelectionMode();
1255 }
1256 
1257 
1258 
1259 void ModulWindow::ShowCursor( sal_Bool bOn )
1260 {
1261     if ( GetEditEngine() )
1262     {
1263         TextView* pView = GetEditEngine()->GetActiveView();
1264         if ( pView )
1265         {
1266             if ( bOn )
1267                 pView->ShowCursor();
1268             else
1269                 pView->HideCursor();
1270         }
1271     }
1272 }
1273 
1274 
1275 Window* __EXPORT ModulWindow::GetLayoutWindow()
1276 {
1277     return pLayout;
1278 }
1279 
1280 void ModulWindow::AssertValidEditEngine()
1281 {
1282     if ( !GetEditEngine() )
1283         GetEditorWindow().CreateEditEngine();
1284 }
1285 
1286 void ModulWindow::Deactivating()
1287 {
1288     if ( GetEditView() )
1289         GetEditView()->EraseVirtualDevice();
1290 }
1291 
1292 sal_uInt16 ModulWindow::StartSearchAndReplace( const SvxSearchItem& rSearchItem, sal_Bool bFromStart )
1293 {
1294     // Mann koennte fuer das blinde Alle-Ersetzen auch auf
1295     // Syntaxhighlighting/Formatierung verzichten...
1296     AssertValidEditEngine();
1297     ExtTextView* pView = GetEditView();
1298     TextSelection aSel;
1299     if ( bFromStart )
1300     {
1301         aSel = pView->GetSelection();
1302         if ( !rSearchItem.GetBackward() )
1303             pView->SetSelection( TextSelection() );
1304         else
1305             pView->SetSelection( TextSelection( TextPaM( 0xFFFFFFFF, 0xFFFF ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
1306     }
1307 
1308     sal_Bool bForward = !rSearchItem.GetBackward();
1309     sal_uInt16 nFound = 0;
1310     if ( ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND ) ||
1311          ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL ) )
1312     {
1313         nFound = pView->Search( rSearchItem.GetSearchOptions() , bForward );
1314     }
1315     else if ( ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE ) ||
1316               ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL ) )
1317     {
1318         if ( !IsReadOnly() )
1319         {
1320             sal_Bool bAll = rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL;
1321             nFound = pView->Replace( rSearchItem.GetSearchOptions() , bAll , bForward );
1322         }
1323     }
1324 
1325     if ( bFromStart && !nFound )
1326         pView->SetSelection( aSel );
1327 
1328     return nFound;
1329 }
1330 
1331 ::svl::IUndoManager* __EXPORT ModulWindow::GetUndoManager()
1332 {
1333     if ( GetEditEngine() )
1334         return &GetEditEngine()->GetUndoManager();
1335     return NULL;
1336 }
1337 
1338 sal_uInt16 __EXPORT ModulWindow::GetSearchOptions()
1339 {
1340     sal_uInt16 nOptions = SEARCH_OPTIONS_SEARCH |
1341                       SEARCH_OPTIONS_WHOLE_WORDS |
1342                       SEARCH_OPTIONS_BACKWARDS |
1343                       SEARCH_OPTIONS_REG_EXP |
1344                       SEARCH_OPTIONS_EXACT |
1345                       SEARCH_OPTIONS_SELECTION |
1346                       SEARCH_OPTIONS_SIMILARITY;
1347 
1348     if ( !IsReadOnly() )
1349     {
1350         nOptions |= SEARCH_OPTIONS_REPLACE;
1351         nOptions |= SEARCH_OPTIONS_REPLACE_ALL;
1352     }
1353 
1354     return nOptions;
1355 }
1356 
1357 void __EXPORT ModulWindow::BasicStarted()
1358 {
1359     if ( XModule().Is() )
1360     {
1361         aStatus.bIsRunning = sal_True;
1362         BreakPointList& rList = GetBreakPoints();
1363         if ( rList.Count() )
1364         {
1365             rList.ResetHitCount();
1366             rList.SetBreakPointsInBasic( xModule );
1367             for ( sal_uInt16 nMethod = 0; nMethod < xModule->GetMethods()->Count(); nMethod++ )
1368             {
1369                 SbMethod* pMethod = (SbMethod*)xModule->GetMethods()->Get( nMethod );
1370                 DBG_ASSERT( pMethod, "Methode nicht gefunden! (NULL)" );
1371                 pMethod->SetDebugFlags( pMethod->GetDebugFlags() | SbDEBUG_BREAK );
1372             }
1373         }
1374     }
1375 }
1376 
1377 void __EXPORT ModulWindow::BasicStopped()
1378 {
1379     aStatus.bIsRunning = sal_False;
1380     GetBreakPointWindow().SetMarkerPos( MARKER_NOMARKER );
1381 }
1382 
1383 BasicEntryDescriptor ModulWindow::CreateEntryDescriptor()
1384 {
1385     ScriptDocument aDocument( GetDocument() );
1386     String aLibName( GetLibName() );
1387     LibraryLocation eLocation = aDocument.getLibraryLocation( aLibName );
1388     String aModName( GetName() );
1389     String aLibSubName;
1390     if( xBasic.Is() && aDocument.isInVBAMode() && XModule().Is() )
1391     {
1392         switch( xModule->GetModuleType() )
1393         {
1394             case script::ModuleType::DOCUMENT:
1395             {
1396                 aLibSubName = String( IDEResId( RID_STR_DOCUMENT_OBJECTS ) );
1397                 uno::Reference< container::XNameContainer > xLib = aDocument.getOrCreateLibrary( E_SCRIPTS, aLibName );
1398                 if( xLib.is() )
1399                 {
1400                     String sObjName;
1401                     ModuleInfoHelper::getObjectName( xLib, aModName, sObjName );
1402                     if( sObjName.Len() )
1403                     {
1404                         aModName.AppendAscii(" (").Append(sObjName).AppendAscii(")");
1405                     }
1406                 }
1407                 break;
1408             }
1409             case script::ModuleType::FORM:
1410                 aLibSubName = String( IDEResId( RID_STR_USERFORMS ) );
1411                 break;
1412             case script::ModuleType::NORMAL:
1413                 aLibSubName = String( IDEResId( RID_STR_NORMAL_MODULES ) );
1414                 break;
1415             case script::ModuleType::CLASS:
1416                 aLibSubName = String( IDEResId( RID_STR_CLASS_MODULES ) );
1417                 break;
1418         }
1419     }
1420     return BasicEntryDescriptor( aDocument, eLocation, aLibName, aLibSubName, aModName, OBJ_TYPE_MODULE );
1421 }
1422 
1423 void ModulWindow::SetReadOnly( sal_Bool b )
1424 {
1425     if ( GetEditView() )
1426         GetEditView()->SetReadOnly( b );
1427 }
1428 
1429 sal_Bool ModulWindow::IsReadOnly()
1430 {
1431     sal_Bool bReadOnly = sal_False;
1432 
1433     if ( GetEditView() )
1434         bReadOnly = GetEditView()->IsReadOnly();
1435 
1436     return bReadOnly;
1437 }
1438 
1439 sal_Bool ModulWindow::IsPasteAllowed()
1440 {
1441     sal_Bool bPaste = sal_False;
1442 
1443     // get clipboard
1444     Reference< datatransfer::clipboard::XClipboard > xClipboard = GetClipboard();
1445     if ( xClipboard.is() )
1446     {
1447         // get clipboard content
1448         const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1449         Reference< datatransfer::XTransferable > xTransf = xClipboard->getContents();
1450         Application::AcquireSolarMutex( nRef );
1451         if ( xTransf.is() )
1452         {
1453             datatransfer::DataFlavor aFlavor;
1454             SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
1455             if ( xTransf->isDataFlavorSupported( aFlavor ) )
1456             {
1457                 bPaste = sal_True;
1458             }
1459         }
1460     }
1461 
1462     return bPaste;
1463 }
1464 
1465 ModulWindowLayout::ModulWindowLayout( Window* pParent ) :
1466     Window( pParent, WB_CLIPCHILDREN ),
1467     aVSplitter( this, WinBits( WB_VSCROLL ) ),
1468     aHSplitter( this, WinBits( WB_HSCROLL ) ),
1469     aWatchWindow( this ),
1470     aStackWindow( this ),
1471     bVSplitted(sal_False),
1472     bHSplitted(sal_False),
1473     m_pModulWindow(0),
1474     m_aImagesNormal(IDEResId(RID_IMGLST_LAYOUT)),
1475     m_aImagesHighContrast(IDEResId(RID_IMGLST_LAYOUT_HC))
1476 {
1477     SetBackground(GetSettings().GetStyleSettings().GetWindowColor());
1478 
1479     aVSplitter.SetSplitHdl( LINK( this, ModulWindowLayout, SplitHdl ) );
1480     aHSplitter.SetSplitHdl( LINK( this, ModulWindowLayout, SplitHdl ) );
1481     aVSplitter.Show();
1482     aHSplitter.Show();
1483 
1484     aWatchWindow.Show();
1485     aStackWindow.Show();
1486 
1487     Color aColor(GetSettings().GetStyleSettings().GetFieldTextColor());
1488     m_aSyntaxColors[TT_UNKNOWN] = aColor;
1489     m_aSyntaxColors[TT_WHITESPACE] = aColor;
1490     m_aSyntaxColors[TT_EOL] = aColor;
1491     m_aColorConfig.AddListener(this);
1492     m_aSyntaxColors[TT_IDENTIFIER]
1493         = Color(m_aColorConfig.GetColorValue(svtools::BASICIDENTIFIER).nColor);
1494     m_aSyntaxColors[TT_NUMBER]
1495         = Color(m_aColorConfig.GetColorValue(svtools::BASICNUMBER).nColor);
1496     m_aSyntaxColors[TT_STRING]
1497         = Color(m_aColorConfig.GetColorValue(svtools::BASICSTRING).nColor);
1498     m_aSyntaxColors[TT_COMMENT]
1499         = Color(m_aColorConfig.GetColorValue(svtools::BASICCOMMENT).nColor);
1500     m_aSyntaxColors[TT_ERROR]
1501         = Color(m_aColorConfig.GetColorValue(svtools::BASICERROR).nColor);
1502     m_aSyntaxColors[TT_OPERATOR]
1503         = Color(m_aColorConfig.GetColorValue(svtools::BASICOPERATOR).nColor);
1504     m_aSyntaxColors[TT_KEYWORDS]
1505         = Color(m_aColorConfig.GetColorValue(svtools::BASICKEYWORD).nColor);
1506 
1507     Font aFont( GetFont() );
1508     Size aSz( aFont.GetSize() );
1509     aSz.Height() *= 3;
1510     aSz.Height() /= 2;
1511     aFont.SetSize( aSz );
1512     aFont.SetWeight( WEIGHT_BOLD );
1513     aFont.SetColor(GetSettings().GetStyleSettings().GetWindowTextColor());
1514     SetFont( aFont );
1515 }
1516 
1517 ModulWindowLayout::~ModulWindowLayout()
1518 {
1519     m_aColorConfig.RemoveListener(this);
1520 }
1521 
1522 void __EXPORT ModulWindowLayout::Resize()
1523 {
1524     // ScrollBars, etc. passiert in BasicIDEShell:Adjust...
1525     ArrangeWindows();
1526 //  Invalidate();
1527 }
1528 
1529 void __EXPORT ModulWindowLayout::Paint( const Rectangle& )
1530 {
1531     DrawText( Point(), String( IDEResId( RID_STR_NOMODULE ) ) );
1532 }
1533 
1534 
1535 void ModulWindowLayout::ArrangeWindows()
1536 {
1537     Size aSz = GetOutputSizePixel();
1538 
1539     // prueffen, ob der Splitter in einem gueltigen Bereich liegt...
1540     long nMinPos = SPLIT_MARGIN;
1541     long nMaxPos = aSz.Height() - SPLIT_MARGIN;
1542 
1543     long nVSplitPos = aVSplitter.GetSplitPosPixel();
1544     long nHSplitPos = aHSplitter.GetSplitPosPixel();
1545     if ( !bVSplitted )
1546     {
1547         // Wenn noch nie gesplitted wurde, Verhaeltniss = 3 : 4
1548         nVSplitPos = aSz.Height() * 3 / 4;
1549         aVSplitter.SetSplitPosPixel( nVSplitPos );
1550     }
1551     if ( !bHSplitted )
1552     {
1553         // Wenn noch nie gesplitted wurde, Verhaeltniss = 2 : 3
1554         nHSplitPos = aSz.Width() * 2 / 3;
1555         aHSplitter.SetSplitPosPixel( nHSplitPos );
1556     }
1557     if ( ( nVSplitPos < nMinPos ) || ( nVSplitPos > nMaxPos ) )
1558         nVSplitPos = ( nVSplitPos < nMinPos ) ? 0 : ( aSz.Height() - SPLIT_HEIGHT );
1559 
1560     Size aXEWSz;
1561     aXEWSz.Width() = aSz.Width();
1562     aXEWSz.Height() = nVSplitPos + 1;
1563     if ( m_pModulWindow )
1564     {
1565         DBG_CHKOBJ( m_pModulWindow, ModulWindow, 0 );
1566         m_pModulWindow->SetPosSizePixel( Point( 0, 0 ), aXEWSz );
1567     }
1568 
1569     aVSplitter.SetDragRectPixel( Rectangle( Point( 0, 0 ), Size( aSz.Width(), aSz.Height() ) ) );
1570     aVSplitter.SetPosPixel( Point( 0, nVSplitPos ) );
1571     aVSplitter.SetSizePixel( Size( aSz.Width(), SPLIT_HEIGHT ) );
1572 
1573     aHSplitter.SetDragRectPixel( Rectangle( Point( 0, nVSplitPos+SPLIT_HEIGHT ), Size( aSz.Width(), aSz.Height() - nVSplitPos - SPLIT_HEIGHT ) ) );
1574     aHSplitter.SetPosPixel( Point( nHSplitPos, nVSplitPos ) );
1575     aHSplitter.SetSizePixel( Size( SPLIT_HEIGHT, aSz.Height() - nVSplitPos ) );
1576 
1577     Size aWWSz;
1578     Point aWWPos( 0, nVSplitPos+SPLIT_HEIGHT );
1579     aWWSz.Width() = nHSplitPos;
1580     aWWSz.Height() = aSz.Height() - aWWPos.Y();
1581     if ( !aWatchWindow.IsFloatingMode() )
1582         aWatchWindow.SetPosSizePixel( aWWPos, aWWSz );
1583 
1584     Size aSWSz;
1585     Point aSWPos( nHSplitPos+SPLIT_HEIGHT, nVSplitPos+SPLIT_HEIGHT );
1586     aSWSz.Width() = aSz.Width() - aSWPos.X();
1587     aSWSz.Height() = aSz.Height() - aSWPos.Y();
1588     if ( !aStackWindow.IsFloatingMode() )
1589         aStackWindow.SetPosSizePixel( aSWPos, aSWSz );
1590 
1591     if ( aStackWindow.IsFloatingMode() && aWatchWindow.IsFloatingMode() )
1592         aHSplitter.Hide();
1593     else
1594         aHSplitter.Show();
1595 
1596     long nHDoubleClickSplitPosX = aSz.Width()-aHSplitter.GetSizePixel().Width();
1597     if ( aHSplitter.GetSplitPosPixel() < nHDoubleClickSplitPosX )
1598         aHSplitter.SetLastSplitPosPixel( nHDoubleClickSplitPosX );
1599 
1600 
1601     long nHDoubleClickSplitPosY = aSz.Height()-aVSplitter.GetSizePixel().Height();
1602     if ( aVSplitter.GetSplitPosPixel() < nHDoubleClickSplitPosY )
1603         aVSplitter.SetLastSplitPosPixel( nHDoubleClickSplitPosY );
1604 }
1605 
1606 IMPL_LINK( ModulWindowLayout, SplitHdl, Splitter *, pSplitter )
1607 {
1608     if ( pSplitter == &aVSplitter )
1609         bVSplitted = sal_True;
1610     else
1611         bHSplitted = sal_True;
1612 
1613     ArrangeWindows();
1614     return 0;
1615 }
1616 
1617 sal_Bool ModulWindowLayout::IsToBeDocked( DockingWindow* pDockingWindow, const Point& rPos, Rectangle& rRect )
1618 {
1619     // prueffen, ob als Dock oder als Child:
1620     // TRUE:    Floating
1621     // FALSE:   Child
1622     Point aPosInMe = ScreenToOutputPixel( rPos );
1623     Size aSz = GetOutputSizePixel();
1624     if ( ( aPosInMe.X() > 0 ) && ( aPosInMe.X() < aSz.Width() ) &&
1625          ( aPosInMe.Y() > 0 ) && ( aPosInMe.Y() < aSz.Height() ) )
1626     {
1627         long nVSplitPos = aVSplitter.GetSplitPosPixel();
1628         long nHSplitPos = aHSplitter.GetSplitPosPixel();
1629         if ( pDockingWindow == &aWatchWindow )
1630         {
1631             if ( ( aPosInMe.Y() > nVSplitPos ) && ( aPosInMe.X() < nHSplitPos ) )
1632             {
1633                 rRect.SetSize( Size( nHSplitPos, aSz.Height() - nVSplitPos ) );
1634                 rRect.SetPos( OutputToScreenPixel( Point( 0, nVSplitPos ) ) );
1635                 return sal_True;
1636             }
1637         }
1638         if ( pDockingWindow == &aStackWindow )
1639         {
1640             if ( ( aPosInMe.Y() > nVSplitPos ) && ( aPosInMe.X() > nHSplitPos ) )
1641             {
1642                 rRect.SetSize( Size( aSz.Width() - nHSplitPos, aSz.Height() - nVSplitPos ) );
1643                 rRect.SetPos( OutputToScreenPixel( Point( nHSplitPos, nVSplitPos ) ) );
1644                 return sal_True;
1645             }
1646         }
1647     }
1648     return sal_False;
1649 }
1650 
1651 void ModulWindowLayout::DockaWindow( DockingWindow* pDockingWindow )
1652 {
1653     if ( pDockingWindow == &aWatchWindow )
1654     {
1655         // evtl. Sonderbehandlung...
1656         ArrangeWindows();
1657     }
1658     else if ( pDockingWindow == &aStackWindow )
1659     {
1660         // evtl. Sonderbehandlung...
1661         ArrangeWindows();
1662     }
1663 #ifdef DBG_UTIL
1664     else
1665         DBG_ERROR( "Wer will sich denn hier andocken ?" );
1666 #endif
1667 }
1668 
1669 void ModulWindowLayout::SetModulWindow( ModulWindow* pModWin )
1670 {
1671     m_pModulWindow = pModWin;
1672     ArrangeWindows();
1673 }
1674 
1675 // virtual
1676 void ModulWindowLayout::DataChanged(DataChangedEvent const & rDCEvt)
1677 {
1678     Window::DataChanged(rDCEvt);
1679     if (rDCEvt.GetType() == DATACHANGED_SETTINGS
1680         && (rDCEvt.GetFlags() & SETTINGS_STYLE) != 0)
1681     {
1682         bool bInvalidate = false;
1683         Color aColor(GetSettings().GetStyleSettings().GetWindowColor());
1684         if (aColor
1685             != rDCEvt.GetOldSettings()->GetStyleSettings().GetWindowColor())
1686         {
1687             SetBackground(Wallpaper(aColor));
1688             bInvalidate = true;
1689         }
1690         aColor = GetSettings().GetStyleSettings().GetWindowTextColor();
1691         if (aColor != rDCEvt.GetOldSettings()->
1692             GetStyleSettings().GetWindowTextColor())
1693         {
1694             Font aFont(GetFont());
1695             aFont.SetColor(aColor);
1696             SetFont(aFont);
1697             bInvalidate = true;
1698         }
1699         if (bInvalidate)
1700             Invalidate();
1701         aColor = GetSettings().GetStyleSettings().GetFieldTextColor();
1702         if (aColor != m_aSyntaxColors[TT_UNKNOWN])
1703         {
1704             m_aSyntaxColors[TT_UNKNOWN] = aColor;
1705             m_aSyntaxColors[TT_WHITESPACE] = aColor;
1706             m_aSyntaxColors[TT_EOL] = aColor;
1707             updateSyntaxHighlighting();
1708         }
1709     }
1710 }
1711 
1712 // virtual
1713 void ModulWindowLayout::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
1714 {
1715     {
1716         Color aColor(m_aColorConfig.GetColorValue(svtools::BASICIDENTIFIER).
1717                      nColor);
1718         bool bChanged = aColor != m_aSyntaxColors[TT_IDENTIFIER];
1719         m_aSyntaxColors[TT_IDENTIFIER] = aColor;
1720         aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICNUMBER).nColor);
1721     if (bChanged || aColor != m_aSyntaxColors[TT_NUMBER])
1722             bChanged = true;
1723         m_aSyntaxColors[TT_NUMBER] = aColor;
1724         aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICSTRING).nColor);
1725         if (bChanged || aColor != m_aSyntaxColors[TT_STRING])
1726             bChanged = true;
1727         m_aSyntaxColors[TT_STRING] = aColor;
1728         aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICCOMMENT).
1729                        nColor);
1730         if (bChanged || aColor != m_aSyntaxColors[TT_COMMENT])
1731             bChanged = true;
1732         m_aSyntaxColors[TT_COMMENT] = aColor;
1733         aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICERROR).nColor);
1734         if (bChanged || aColor != m_aSyntaxColors[TT_ERROR])
1735             bChanged = true;
1736         m_aSyntaxColors[TT_ERROR] = aColor;
1737         aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICOPERATOR).
1738                        nColor);
1739         if (bChanged || aColor != m_aSyntaxColors[TT_OPERATOR])
1740             bChanged = true;
1741         m_aSyntaxColors[TT_OPERATOR] = aColor;
1742         aColor = Color(m_aColorConfig.GetColorValue(svtools::BASICKEYWORD).
1743                        nColor);
1744         if (bChanged || aColor != m_aSyntaxColors[TT_KEYWORDS])
1745             bChanged = true;
1746         m_aSyntaxColors[TT_KEYWORDS] = aColor;
1747         if (bChanged)
1748             updateSyntaxHighlighting();
1749     }
1750 }
1751 
1752 void ModulWindowLayout::updateSyntaxHighlighting()
1753 {
1754     if (m_pModulWindow != 0)
1755     {
1756         EditorWindow & rEditor = m_pModulWindow->GetEditorWindow();
1757         sal_uLong nCount = rEditor.GetEditEngine()->GetParagraphCount();
1758         for (sal_uLong i = 0; i < nCount; ++i)
1759             rEditor.DoDelayedSyntaxHighlight(i);
1760     }
1761 }
1762 
1763 Image ModulWindowLayout::getImage(sal_uInt16 nId, bool bHighContrastMode) const
1764 {
1765     return (bHighContrastMode ? m_aImagesHighContrast : m_aImagesNormal).
1766         GetImage(nId);
1767 }
1768