merge the formfield patch from ooo-build
[ooovba.git] / basic / source / app / textedit.cxx
blobe07cc908857c0b26aa9d355793fdd0c34fecfd64
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: textedit.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
33 #include <tools/stream.hxx>
34 #include <svtools/texteng.hxx>
35 #include <svtools/textview.hxx>
36 #include <svtools/txtattr.hxx>
37 #include <basic/sbxmeth.hxx>
38 #ifndef _BASIC_TTRESHLP_HXX
39 #include <basic/ttstrhlp.hxx>
40 #endif
42 #include "basic.hrc"
43 #include "textedit.hxx"
44 #include "appedit.hxx"
45 #include "brkpnts.hxx"
46 #include <basic/testtool.hxx> // defines for syntax highlighting
48 TextEditImp::TextEditImp( AppEdit* pParent, const WinBits& aBits )
49 : Window( pParent, aBits )
50 , pAppEdit( pParent )
51 , bHighlightning( FALSE )
52 , bDoSyntaxHighlight( FALSE )
53 , bDelayHighlight( TRUE )
54 , nTipId( 0 )
55 , bViewMoved( FALSE )
57 pTextEngine = new TextEngine();
58 pTextEngine->SetMaxTextLen( STRING_MAXLEN );
59 pTextEngine->EnableUndo( TRUE );
61 pTextView = new TextView( pTextEngine, this );
62 pTextEngine->InsertView( pTextView );
63 pTextEngine->SetModified( FALSE );
65 aSyntaxIdleTimer.SetTimeout( 200 );
66 aSyntaxIdleTimer.SetTimeoutHdl( LINK( this, TextEditImp, SyntaxTimerHdl ) );
68 aImplSyntaxIdleTimer.SetTimeout( 1 );
69 aImplSyntaxIdleTimer.SetTimeoutHdl( LINK( this, TextEditImp, SyntaxTimerHdl ) );
71 StartListening( *pTextEngine );
73 HideTipTimer.SetTimeout( 5000 ); // 5 seconds
74 ShowTipTimer.SetTimeout( 500 ); // 1/2 seconds
75 HideTipTimer.SetTimeoutHdl( LINK( this, TextEditImp, HideVarContents ) );
76 ShowTipTimer.SetTimeoutHdl( LINK( this, TextEditImp, ShowVarContents ) );
79 TextEditImp::~TextEditImp()
81 pTextEngine->RemoveView( pTextView );
82 delete pTextView;
83 delete pTextEngine;
86 BOOL TextEditImp::ViewMoved()
88 BOOL bOld = bViewMoved;
89 bViewMoved = FALSE;
90 return bOld;
93 void TextEditImp::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
95 (void) rBC; /* avoid warning about unused parameter */
96 if ( rHint.ISA( TextHint ) )
98 const TextHint& rTextHint = (const TextHint&)rHint;
99 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
101 pAppEdit->pHScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
102 pAppEdit->pVScroll->SetThumbPos( pTextView->GetStartDocPos().Y() );
103 if ( ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow() )
104 ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->Scroll( 0, ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->GetCurYOffset() - pTextView->GetStartDocPos().Y() );
105 bViewMoved = TRUE;
107 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
109 if ( pTextView->GetStartDocPos().Y() )
111 long nOutHeight = GetOutputSizePixel().Height();
112 long nTextHeight = pTextEngine->GetTextHeight();
113 if ( nTextHeight < nOutHeight )
114 pTextView->Scroll( 0, pTextView->GetStartDocPos().Y() );
117 pAppEdit->SetScrollBarRanges();
119 else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
121 ULONG nWidth = pTextEngine->CalcTextWidth();
122 if ( (ULONG)nWidth != pAppEdit->nCurTextWidth )
124 pAppEdit->nCurTextWidth = nWidth;
125 if ( pAppEdit->pHScroll )
126 { // Initialization finished?
127 pAppEdit->pHScroll->SetRange( Range( 0, (long)nWidth) );
128 pAppEdit->pHScroll->SetThumbPos( pTextView->GetStartDocPos().X() );
132 else if( rTextHint.GetId() == TEXT_HINT_PARAINSERTED )
134 if ( ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow() )
135 ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->AdjustBreakpoints( rTextHint.GetValue()+1, TRUE );
137 else if( rTextHint.GetId() == TEXT_HINT_PARAREMOVED )
139 if ( ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow() )
140 ((TextEdit*)(pAppEdit->pDataEdit))->GetBreakpointWindow()->AdjustBreakpoints( rTextHint.GetValue()+1, FALSE );
142 // Itchy adaption for two signs at line ends instead of one (hard coded default)
143 pTextEngine->SetMaxTextLen( STRING_MAXLEN - pTextEngine->GetParagraphCount() );
145 else if( rTextHint.GetId() == TEXT_HINT_FORMATPARA )
147 DoDelayedSyntaxHighlight(
148 sal::static_int_cast< xub_StrLen >( rTextHint.GetValue() ) );
149 if ( pTextView->GetTextEngine()->IsModified() )
150 ModifyHdl.Call( NULL );
155 #define TEXTATTR_SPECHIAL 55
156 class TextAttribSpechial : public TextAttrib
158 private:
159 FontWeight maFontWeight;
161 public:
162 TextAttribSpechial( const FontWeight& rFontWeight );
163 TextAttribSpechial( const TextAttribSpechial& rAttr );
164 ~TextAttribSpechial() {;}
166 virtual void SetFont( Font& rFont ) const;
167 virtual TextAttrib* Clone() const;
168 virtual int operator==( const TextAttrib& rAttr ) const;
171 TextAttribSpechial::TextAttribSpechial( const FontWeight& rFontWeight )
172 : TextAttrib( TEXTATTR_SPECHIAL ), maFontWeight( rFontWeight )
175 TextAttribSpechial::TextAttribSpechial( const TextAttribSpechial& rAttr )
176 : TextAttrib( rAttr ), maFontWeight( rAttr.maFontWeight )
179 void TextAttribSpechial::SetFont( Font& rFont ) const
181 rFont.SetWeight( maFontWeight );
184 TextAttrib* TextAttribSpechial::Clone() const
186 return new TextAttribSpechial( *this );
189 int TextAttribSpechial::operator==( const TextAttrib& rAttr ) const
191 return ( ( TextAttrib::operator==(rAttr ) ) &&
192 ( maFontWeight == ((const TextAttribSpechial&)rAttr).maFontWeight ) );
195 void TextEditImp::ImpDoHighlight( const String& rSource, ULONG nLineOff )
197 SbTextPortions aPortionList;
198 pAppEdit->GetBasicFrame()->Basic().Highlight( rSource, aPortionList );
200 USHORT nCount = aPortionList.Count();
201 if ( !nCount )
202 return;
204 SbTextPortion& rLast = aPortionList[nCount-1];
205 if ( rLast.nStart > rLast.nEnd ) // Nur bis Bug von MD behoben
207 #if OSL_DEBUG_LEVEL > 1
208 DBG_ERROR( "MD-Bug nicht beseitigt!" );
209 #endif
210 nCount--;
211 aPortionList.Remove( nCount);
212 if ( !nCount )
213 return;
216 // here is the postprocessing for types for the TestTool
217 USHORT i;
218 BOOL bWasTTControl = FALSE;
219 for ( i = 0; i < aPortionList.Count(); i++ )
221 SbTextPortion& r = aPortionList[i];
222 // DBG_ASSERT( r.nStart <= r.nEnd, "Highlight: Start > End?" );
223 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoben
224 continue;
226 SbTextType eType = r.eType;
227 Color aColor;
228 switch ( eType )
230 case SB_SYMBOL:
232 String aSymbol = rSource.Copy( r.nStart, r.nEnd - r.nStart +1 );
233 r.eType = pAppEdit->GetBasicFrame()->Basic().GetSymbolType( aSymbol, bWasTTControl );
235 if ( r.eType == TT_CONTROL )
236 bWasTTControl = TRUE;
237 else
238 bWasTTControl = FALSE;
240 break;
241 case SB_PUNCTUATION:
243 String aPunctuation = rSource.Copy( r.nStart, r.nEnd - r.nStart +1 );
244 if ( aPunctuation.CompareToAscii( "." ) != COMPARE_EQUAL )
245 bWasTTControl = FALSE;
247 break;
248 default:
249 bWasTTControl = FALSE;
253 // Es muessen nur die Blanks und Tabs mit attributiert werden.
254 // If there are two equal attributes one after another,
255 // they are optimized by the EditEngine.
256 xub_StrLen nLastEnd = 0;
257 #ifdef DBG_UTIL
258 xub_StrLen nLine1 = aPortionList[0].nLine;
259 #endif
260 for ( i = 0; i < nCount; i++ )
262 SbTextPortion& r = aPortionList[i];
263 DBG_ASSERT( r.nLine == nLine1, "doch mehrere Zeilen ?" );
264 DBG_ASSERT( r.nStart <= r.nEnd, "Highlight: Start > End?" );
265 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoben
266 continue;
268 if ( r.nStart > nLastEnd )
270 // Kann ich mich drauf verlassen, dass alle ausser
271 // Blank und Tab gehighlightet wird ?!
272 r.nStart = nLastEnd;
274 nLastEnd = r.nEnd+1;
275 if ( ( i == (nCount-1) ) && ( r.nEnd < rSource.Len() ) )
276 r.nEnd = rSource.Len()-1;
279 BOOL bWasModified = pTextEngine->IsModified();
280 for ( i = 0; i < aPortionList.Count(); i++ )
282 SbTextPortion& r = aPortionList[i];
283 // DBG_ASSERT( r.nStart <= r.nEnd, "Highlight: Start > End?" );
284 if ( r.nStart > r.nEnd ) // Nur bis Bug von MD behoben
285 continue;
287 SbTextType eCol = r.eType;
288 Color aColor;
289 ULONG nLine = nLineOff+r.nLine-1; // -1, because BASIC starts with 1
290 switch ( +eCol )
292 case SB_KEYWORD:
293 aColor = Color( COL_BLUE );
294 break;
295 case SB_SYMBOL:
296 aColor = Color( RGB_COLORDATA( 0x00, 0x60, 0x00 ) );
297 break;
298 case SB_STRING:
299 aColor = Color( COL_RED );
300 break;
301 case SB_NUMBER:
302 aColor = Color( COL_MAGENTA );
303 break;
304 case SB_PUNCTUATION:
305 aColor = Color( COL_BLACK );
306 break;
307 case SB_COMMENT:
308 aColor = Color( COL_GRAY );
309 break;
310 case TT_KEYWORD:
311 case TT_LOCALCMD:
312 aColor = Color( COL_LIGHTBLUE );
313 break;
314 case TT_REMOTECMD:
315 aColor = Color( RGB_COLORDATA( 0x00, 0xB0, 0xB0 ) );
316 break;
317 case TT_CONTROL:
318 case TT_SLOT:
319 aColor = Color( RGB_COLORDATA( 0x00, 0xB0, 0x00 ) );
320 break;
321 case TT_METHOD:
322 aColor = Color( RGB_COLORDATA( 0x00, 0xB0, 0x00 ) );
323 break;
324 case TT_NOMETHOD:
326 aColor = Color( COL_RED );
327 pTextEngine->SetAttrib( TextAttribSpechial( WEIGHT_BOLD ), nLine, r.nStart, r.nEnd+1 );
329 break;
330 default:
332 aColor = Color( RGB_COLORDATA( 0xff, 0x80, 0x80 ) );
333 DBG_ERROR( "Unknown syntax color" );
336 pTextEngine->SetAttrib( TextAttribFontColor( aColor ), nLine, r.nStart, r.nEnd+1 );
338 // Highlighting should not modify the text
339 pTextEngine->SetModified( bWasModified );
342 void TextEditImp::DoSyntaxHighlight( ULONG nPara )
344 // Due to delayed syntax highlight it can happend that the
345 // paragraph does no longer exist
346 if ( nPara < pTextEngine->GetParagraphCount() )
348 // leider weis ich nicht, ob genau diese Zeile Modified() ...
349 // if ( pProgress )
350 // pProgress->StepProgress();
351 pTextEngine->RemoveAttribs( nPara );
352 String aSource( pTextEngine->GetText( nPara ) );
353 ImpDoHighlight( aSource, nPara );
357 void TextEditImp::DoDelayedSyntaxHighlight( xub_StrLen nPara )
359 // Paragraph is added to 'List', processed in TimerHdl.
360 // => Do not manipulate paragraphs while EditEngine is formatting
361 // if ( pProgress )
362 // pProgress->StepProgress();
364 if ( !bHighlightning && bDoSyntaxHighlight )
366 if ( bDelayHighlight )
368 aSyntaxLineTable.Insert( nPara, (void*)(ULONG)1 );
369 aSyntaxIdleTimer.Start();
371 else
372 DoSyntaxHighlight( nPara );
376 IMPL_LINK( TextEditImp, SyntaxTimerHdl, Timer *, EMPTYARG )
378 DBG_ASSERT( pTextView, "Not yet a View but Syntax-Highlight ?!" );
379 pTextEngine->SetUpdateMode( FALSE );
381 bHighlightning = TRUE;
382 USHORT nLine;
383 while ( aSyntaxLineTable.First() && !Application::AnyInput( INPUT_MOUSEANDKEYBOARD ) )
385 nLine = (USHORT)aSyntaxLineTable.GetCurKey();
386 DoSyntaxHighlight( nLine );
387 aSyntaxLineTable.Remove( nLine );
388 /* if ( Application::AnyInput() )
390 aSyntaxIdleTimer.Start(); // Starten, falls wir in einem Dialog landen
391 pTextView->ShowCursor( TRUE, TRUE );
392 pTextEngine->SetUpdateMode( TRUE );
393 bHighlightning = FALSE;
394 GetpApp()->Reschedule();
395 bHighlightning = TRUE;
396 pTextEngine->SetUpdateMode( FALSE );
400 BOOL bWasModified = pTextEngine->IsModified();
401 if ( aSyntaxLineTable.Count() > 3 ) // Without VDev
403 pTextEngine->SetUpdateMode( TRUE );
404 pTextView->ShowCursor( TRUE, TRUE );
406 else
407 pTextEngine->SetUpdateMode( TRUE ); // ! With VDev
408 // pTextView->ForceUpdate();
410 // SetUpdateMode( TRUE ) soll kein Modify setzen
411 pTextEngine->SetModified( bWasModified );
413 // SyntaxTimerHdl wird gerufen, wenn Text-Aenderung
414 // => gute Gelegenheit, Textbreite zu ermitteln!
415 // long nPrevTextWidth = nCurTextWidth;
416 // nCurTextWidth = pTextEngine->CalcTextWidth();
417 // if ( nCurTextWidth != nPrevTextWidth )
418 // SetScrollBarRanges();
419 bHighlightning = FALSE;
421 if ( aSyntaxLineTable.First() )
422 aImplSyntaxIdleTimer.Start();
424 // while ( Application::AnyInput() )
425 // Application::Reschedule(); // Reschedule, da der UserEvent keine Paints etc. durchlässt
427 return 0;
430 void TextEditImp::InvalidateSyntaxHighlight()
432 for ( xub_StrLen i = 0; i < pTextEngine->GetParagraphCount(); i++ )
433 DoDelayedSyntaxHighlight( i );
436 void TextEditImp::SyntaxHighlight( BOOL bNew )
438 if ( ( bNew && bDoSyntaxHighlight ) || ( !bNew && !bDoSyntaxHighlight ) )
439 return;
441 bDoSyntaxHighlight = bNew;
442 if ( !pTextEngine )
443 return;
446 if ( bDoSyntaxHighlight )
448 InvalidateSyntaxHighlight();
450 else
452 aSyntaxIdleTimer.Stop();
453 pTextEngine->SetUpdateMode( FALSE );
454 for ( ULONG i = 0; i < pTextEngine->GetParagraphCount(); i++ )
455 pTextEngine->RemoveAttribs( i );
457 // pTextEngine->QuickFormatDoc();
458 pTextEngine->SetUpdateMode( TRUE );
459 pTextView->ShowCursor(TRUE, TRUE );
464 void TextEditImp::SetFont( const Font& rNewFont )
466 pTextEngine->SetFont(rNewFont);
469 BOOL TextEditImp::IsModified()
471 return pTextEngine->IsModified();
474 void TextEditImp::KeyInput( const KeyEvent& rKeyEvent )
476 BOOL bWasModified = pTextView->GetTextEngine()->IsModified();
477 pTextView->GetTextEngine()->SetModified( FALSE );
479 if ( !pTextView->KeyInput( rKeyEvent ) )
480 Window::KeyInput( rKeyEvent );
482 if ( pTextView->GetTextEngine()->IsModified() )
483 ModifyHdl.Call( NULL );
484 else
485 pTextView->GetTextEngine()->SetModified( bWasModified );
488 void TextEditImp::Paint( const Rectangle& rRect ){ pTextView->Paint( rRect );}
489 void TextEditImp::MouseButtonUp( const MouseEvent& rMouseEvent ){ pTextView->MouseButtonUp( rMouseEvent );}
490 //void TextEditImp::MouseButtonDown( const MouseEvent& rMouseEvent ){ pTextView->MouseButtonDown( rMouseEvent );}
491 //void TextEditImp::MouseMove( const MouseEvent& rMouseEvent ){ pTextView->MouseMove( rMouseEvent );}
492 //void TextEditImp::Command( const CommandEvent& rCEvt ){ pTextView->Command( rCEvt );}
493 //BOOL TextEditImp::Drop( const DropEvent& rEvt ){ return FALSE /*pTextView->Drop( rEvt )*/;}
494 //BOOL TextEditImp::QueryDrop( DropEvent& rEvt ){ return FALSE /*pTextView->QueryDrop( rEvt )*/;}
497 void TextEditImp::Command( const CommandEvent& rCEvt )
499 switch( rCEvt.GetCommand() ) {
500 case COMMAND_CONTEXTMENU:
501 case COMMAND_WHEEL:
502 GetParent()->Command( rCEvt );
503 break;
504 default:
505 pTextView->Command( rCEvt );
510 void TextEditImp::MouseButtonDown( const MouseEvent& rMouseEvent )
512 pTextView->MouseButtonDown( rMouseEvent );
513 HideVarContents( NULL );
514 ShowTipTimer.Stop();
518 void TextEditImp::MouseMove( const MouseEvent& rMEvt )
520 pTextView->MouseMove( rMEvt );
521 HideVarContents( NULL );
522 if ( rMEvt.GetButtons() == 0 )
523 ShowTipTimer.Start();
524 if ( rMEvt.IsLeaveWindow() )
525 ShowTipTimer.Stop();
529 IMPL_LINK( TextEditImp, HideVarContents, void*, EMPTYARG )
531 if ( nTipId )
533 Help::HideTip( nTipId );
534 nTipId = 0;
535 aTipWord = String();
537 return 0;
540 static const char cSuffixes[] = "%&!#@$";
543 SbxBase* TextEditImp::GetSbxAtMousePos( String &aWord )
545 Point aPos = GetPointerPosPixel();
546 Point aDocPos = pTextView->GetDocPos( aPos );
547 aWord = pTextEngine->GetWord( pTextEngine->GetPaM( aDocPos ) );
549 if ( aWord.Len() /*&& !Application::GetAppInternational().IsNumeric( aWord )*/ )
551 xub_StrLen nLastChar = aWord.Len()-1;
552 String aSuffixes = CUniString( cSuffixes );
553 if ( aSuffixes.Search( aWord.GetChar(nLastChar) ) != STRING_NOTFOUND )
554 aWord.Erase( nLastChar, 1 );
555 // because perhaps TestTools throws an error
556 BOOL bWasError = SbxBase::IsError();
557 pAppEdit->GetBasicFrame()->Basic().DebugFindNoErrors( TRUE );
558 SbxBase* pSBX = StarBASIC::FindSBXInCurrentScope( aWord );
559 pAppEdit->GetBasicFrame()->Basic().DebugFindNoErrors( FALSE );
560 DBG_ASSERT( !( !bWasError && SbxBase::IsError()), "Error generated while retrieving Variable data for viewing" );
561 if ( !bWasError && SbxBase::IsError() )
562 SbxBase::ResetError();
564 return pSBX;
566 return NULL;
570 IMPL_LINK( TextEditImp, ShowVarContents, void*, EMPTYARG )
572 String aWord;
573 SbxBase* pSBX = GetSbxAtMousePos( aWord );
574 String aHelpText;
575 Point aPos = GetPointerPosPixel();
577 if ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
579 SbxVariable* pVar = (SbxVariable*)pSBX;
580 SbxDataType eType = pVar->GetType();
581 if ( eType == SbxOBJECT )
583 // Can cause a crash: Type == Object does not mean pVar == Object
584 if ( pVar->GetObject() && pVar->GetObject()->ISA( SbxObject ) )
585 aHelpText = ((SbxObject*)(pVar->GetObject()))->GetClassName();
586 else
587 aHelpText = CUniString("Object");
589 else if ( eType & SbxARRAY )
590 aHelpText = CUniString("{...}");
591 else if ( eType != SbxEMPTY )
593 aHelpText = pVar->GetName();
594 if ( !aHelpText.Len() ) // Name is not copied in arguments
595 aHelpText = aWord;
596 aHelpText += '=';
597 aHelpText += pVar->GetString();
602 if ( aHelpText.Len() && aTipPos != aPos && aTipWord != aWord )
604 if ( nTipId )
605 Help::HideTip( nTipId );
606 nTipId = Help::ShowTip( this, Rectangle(), aHelpText );
608 HideTipTimer.Start();
609 aTipWord = aWord;
610 aTipPos = aPos;
612 if ( nTipId && aTipPos != aPos )
614 Help::HideTip( nTipId );
615 nTipId = 0;
616 aTipWord = String();
619 return 0;
623 void TextEditImp::BuildKontextMenu( PopupMenu *&pMenu )
625 String aWord;
626 SbxBase* pSBX = GetSbxAtMousePos( aWord );
627 if ( pSBX && pSBX->ISA( SbxVariable ) && !pSBX->ISA( SbxMethod ) )
629 SbxVariable* pVar = (SbxVariable*)pSBX;
630 SbxDataType eType = pVar->GetType();
632 if ( ( eType & ( SbxVECTOR | SbxARRAY | SbxBYREF )) == 0 )
636 Boolean
637 Currency
638 Date
639 Double
640 Integer
641 Long
642 Object
643 Single
644 String
645 Variant(Empty)
647 switch ( eType )
649 case SbxBOOL:
650 // case SbxCURRENCY:
651 // case SbxDATE:
652 case SbxDOUBLE:
653 case SbxINTEGER:
654 case SbxLONG:
655 // case SbxOBJECT: // cannot be edited
656 case SbxSINGLE:
657 case SbxSTRING:
659 case SbxVARIANT: // does not occure, instead SbxEMPTY
660 case SbxEMPTY:
662 pAppEdit->GetBasicFrame()->SetEditVar( pVar );
663 if ( !pMenu )
664 pMenu = new PopupMenu();
665 else
666 pMenu->InsertSeparator();
668 pMenu->InsertItem( RID_POPUPEDITVAR, ((BasicFrame*)GetpApp()->GetAppWindow())->GenRealString( GEN_RES_STR1( IDS_EDIT_VAR, aWord ) ) );
670 break;
671 default:
681 DBG_NAME(TextEdit)
683 TextEdit::TextEdit( AppEdit* pParent, const WinBits& aBits )
684 : pBreakpointWindow( NULL )
685 , bFileWasUTF8( FALSE )
686 , bSaveAsUTF8( FALSE )
687 , aEdit( pParent, aBits | WB_NOHIDESELECTION )
689 DBG_CTOR(TextEdit,0);
692 TextEdit::~TextEdit()
693 {DBG_DTOR(TextEdit,0);}
695 void TextEdit::Highlight( ULONG nLine, xub_StrLen nCol1, xub_StrLen nCol2 )
697 if ( nLine ) // Should not occure but at 'Sub expected' in first line
698 nLine--;
700 String s = aEdit.pTextEngine->GetText( nLine );
702 if( nCol1 == STRING_NOTFOUND )
704 // No column given
705 nCol1 = 0;
706 nCol2 = STRING_NOTFOUND;
708 if( nCol2 == STRING_NOTFOUND )
710 nCol2 = s.Len();
712 // Adaption to the Precompiler | EditText != Compilied Text
713 if ( nCol2 > s.Len() )
714 nCol2 = s.Len();
715 if ( nCol1 >= nCol2 )
716 nCol1 = 0;
718 // Because nCol2 *may* point after the current statement
719 // (because the next one starts there) there are space
720 // that must be removed
721 BOOL bColon = FALSE;
723 while ( s.GetChar( nCol2 ) == ' ' && nCol2 > nCol1 && !bColon )
725 nCol2--;
726 if ( s.GetChar( nCol2 ) == ':' )
728 nCol2--;
729 bColon = TRUE;
733 aEdit.ViewMoved();
734 aEdit.pTextView->SetSelection( TextSelection(TextPaM(nLine,nCol2+1), TextPaM(nLine,nCol1)) );
735 if ( aEdit.ViewMoved() )
737 aEdit.pTextView->SetSelection( TextSelection(TextPaM(TEXT_PARA_ALL,1)) ); // fix #105169#
738 aEdit.pTextView->SetSelection( TextSelection(TextPaM((nLine>=2?nLine-2:0),nCol2+1)) );
739 aEdit.pTextView->SetSelection( TextSelection(TextPaM(nLine,nCol2+1), TextPaM(nLine,nCol1)) );
744 void TextEdit::Delete(){ aEdit.pTextView->KeyInput( KeyEvent( 0, KeyCode( KEYFUNC_DELETE ) )); }
745 void TextEdit::Cut(){ aEdit.pTextView->Cut(); }
746 void TextEdit::Copy(){ aEdit.pTextView->Copy(); }
747 void TextEdit::Paste(){ aEdit.pTextView->Paste(); }
748 void TextEdit::Undo(){ aEdit.pTextView->Undo(); }
749 void TextEdit::Redo(){ aEdit.pTextView->Redo(); }
750 String TextEdit::GetSelected(){ return aEdit.pTextView->GetSelected(); }
751 TextSelection TextEdit::GetSelection() const{ return aEdit.pTextView->GetSelection(); }
752 void TextEdit::SetSelection( const TextSelection& rSelection ){ aEdit.pTextView->SetSelection( rSelection ); }
754 USHORT TextEdit::GetLineNr() const
756 return sal::static_int_cast< USHORT >(
757 aEdit.pTextView->GetSelection().GetEnd().GetPara()+1);
760 void TextEdit::ReplaceSelected( const String& rStr ){ aEdit.pTextView->InsertText(rStr); }
761 BOOL TextEdit::IsModified(){ return aEdit.IsModified(); }
763 String TextEdit::GetText() const
765 return aEdit.pTextEngine->GetText( GetSystemLineEnd() );
768 void TextEdit::SetText( const String& rStr ){ aEdit.pTextEngine->SetText(rStr); aEdit.pTextEngine->SetModified( FALSE ); }
769 void TextEdit::SetModifyHdl( Link l ){ aEdit.SetModifyHdl(l); }
770 BOOL TextEdit::HasText() const { return aEdit.pTextEngine->GetTextLen() > 0; }
772 // Search from the beginning or at mark + 1
773 BOOL TextEdit::Find( const String& s )
775 DBG_CHKTHIS(TextEdit,0);
777 TextSelection aSelection = aEdit.pTextView->GetSelection();
778 ULONG nPara = aSelection.GetStart().GetPara();
779 xub_StrLen nIndex = aSelection.GetStart().GetIndex();
781 if ( aSelection.HasRange() )
782 nIndex ++;
784 while ( nPara <= aEdit.pTextEngine->GetParagraphCount() )
786 String aText = aEdit.pTextEngine->GetText( nPara );
788 nIndex = aText.Search( s, nIndex );
789 if( nIndex != STRING_NOTFOUND )
791 aEdit.pTextView->SetSelection( TextSelection( TextPaM( nPara, nIndex ), TextPaM( nPara, nIndex + s.Len() ) ) );
792 return TRUE;
794 nIndex = 0;
795 nPara++;
797 return FALSE;
800 BOOL TextEdit::Load( const String& aName )
802 DBG_CHKTHIS(TextEdit,0);
803 BOOL bOk = TRUE;
804 SvFileStream aStrm( aName, STREAM_STD_READ );
805 if( aStrm.IsOpen() )
807 String aText, aLine, aLineBreak;
808 BOOL bIsFirstLine = TRUE;
809 aLineBreak += '\n';
810 aLineBreak.ConvertLineEnd();
811 rtl_TextEncoding aFileEncoding = RTL_TEXTENCODING_IBM_850;
812 while( !aStrm.IsEof() && bOk )
814 aStrm.ReadByteStringLine( aLine, aFileEncoding );
815 if ( bIsFirstLine && IsTTSignatureForUnicodeTextfile( aLine ) )
817 aFileEncoding = RTL_TEXTENCODING_UTF8;
818 bFileWasUTF8 = TRUE;
820 else
822 if ( !bIsFirstLine )
823 aText += aLineBreak;
824 aText += aLine;
825 bIsFirstLine = FALSE;
827 if( aStrm.GetError() != SVSTREAM_OK )
828 bOk = FALSE;
830 SetText( aText );
832 else
833 bOk = FALSE;
834 return bOk;
837 BOOL TextEdit::Save( const String& aName )
839 DBG_CHKTHIS(TextEdit,0);
840 BOOL bOk = TRUE;
841 SvFileStream aStrm( aName, STREAM_STD_WRITE | STREAM_TRUNC );
842 rtl_TextEncoding aFileEncoding = RTL_TEXTENCODING_IBM_850;
843 if( aStrm.IsOpen() )
845 if ( bFileWasUTF8 || bSaveAsUTF8 )
847 aStrm << TT_SIGNATURE_FOR_UNICODE_TEXTFILES;
848 aStrm << sal_Char(_LF);
849 aFileEncoding = RTL_TEXTENCODING_UTF8;
851 String aSave = GetText();
852 aSave.ConvertLineEnd(LINEEND_LF);
853 aStrm << ByteString( aSave, aFileEncoding ).GetBuffer();
854 if( aStrm.GetError() != SVSTREAM_OK )
855 bOk = FALSE;
856 else
857 aEdit.pTextEngine->SetModified(FALSE);
858 } else bOk = FALSE;
859 return bOk;
863 void TextEdit::BuildKontextMenu( PopupMenu *&pMenu )
865 DataEdit::BuildKontextMenu( pMenu );
866 aEdit.BuildKontextMenu( pMenu );