void DisassemblyTextCtrl::OnDclick(wxMouseEvent& event)
{

        if(GetStatus())
        {
            SetStatus(0);
           PluginsArray plugins = Manager::Get()->GetPluginManager()->GetDebuggerOffers();
            if (plugins.GetCount())
            {
                cbDebuggerPlugin* dbg = (cbDebuggerPlugin*)plugins[0];
                if (dbg)
                {
                    // is the debugger running?
                    if (dbg->IsRunning())
                    {
                        dbg->StepByStep();
                    }
                }
            }
        }
        int LineNum = GetCurrentLine();
        int L2 = GetCurrentLine();
        wxString LineText,SourceFile;
       unsigned long SourceLine=0;

        while(LineNum > 0)
        {
            LineText = GetLine(LineNum--);
            if(reRelativePath.Matches(LineText))
            break;
        }

        if(LineText.IsEmpty())
        return ;

        LineText.AfterLast(_T(':')).ToULong(&SourceLine,10);
        SourceFile = Manager::Get()->GetProjectManager()->GetActiveProject()->GetBasePath();
        SourceFile  <<  LineText.Before(_T(':'));



        SyncEditor(LineText.Before(_T(':')),SourceLine,true);

        SetReadOnly(false);
        MarkerDeleteAll(DEBUG_MARKER);
        MarkerAdd(SourceLine,DEBUG_MARKER);


        SetReadOnly(true);
    //wxMessageBox(wxString::Format(_T("%s:%d"),SourceFile.c_str(),SourceLine));
     event.Skip();

}
void MaterialScriptEditor::OnCharAdded(wxScintillaEvent &event)
{
    ScintillaEditor::OnCharAdded(event);

    char ch = event.GetKey();
    if(getCallTipManager().isTrigger(ch))
    {
        int lineNum = GetCurrentLine();
        if(lineNum != -1)
        {
            wxString line = GetLine(lineNum);
            int pos = GetCurrentPos() - 1;

            wxString word("");
            wxChar ch;
            while(pos)
            {
                ch = GetCharAt(--pos);
                if(ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t' && ch != '{' && ch != '}') word.Prepend(ch);
                else break;
            }

            wxString* tips = getCallTipManager().find(word);
            if(tips != NULL)
            {
                CallTipShow(pos, *tips);
            }
        }
    }
}
Exemple #3
0
void Navigator::Navigate()
{
	if(navigating)
		return;
	navigating = true;
	int ii = list.GetCursor();
	if(theide && ii >= 0 && ii < litem.GetCount()) {
		int ln = GetCurrentLine() + 1;
		const NavItem& m = *litem[ii];
		if(m.kind == KIND_LINE || IsNull(search)) {
			theide->GotoPos(Null, m.line);
			if(m.kind == KIND_LINE) { // Go to line - restore file view
				search.Clear();
				Search();
				navigating = false;
			}
			SyncCursor();
		}
		else {
			Vector<NavLine> l = GetNavLines(m);
			int q = l.GetCount() - 1;
			for(int i = 0; i < l.GetCount(); i++)
				if(GetSourceFilePath(l[i].file) == NormalizeSourcePath(theide->editfile) && l[i].line == ln) {
					q = (i + l.GetCount() + 1) % l.GetCount();
					break;
				}
			if(q >= 0 && q < l.GetCount()) {
				String path = GetSourceFilePath(l[q].file);
				if(!theide->GotoDesignerFile(path, m.nest, m.name, l[q].line))
					theide->GotoPos(path, l[q].line);
			}
		}
	}
	navigating = false;
}
Exemple #4
0
/*
 * IMDelete - handle DEL key pressed in insert mode
 */
vi_rc IMDelete( void )
{
    int wlen;

    if( CurrentFile == NULL ) {
        return( ERR_NO_FILE );
    }

    startNewLineUndo();
    wlen = WorkLine->len + 1;
    if( wlen == 0 ) {
        wlen = CurrentLine->len + 1;
    }
    if( EditFlags.Modeless && CurrentPos.column == wlen && CurrentLine->next ) {
        /* go to beginning of next line */
        GoToLineRelCurs( CurrentPos.line + 1 );
        GoToColumnOK( 1 );
        GetCurrentLine();
    } else {
        GoToColumn( CurrentPos.column + 1, wlen );
        if( CurrentPos.column != wlen - 1 || abbrevCnt == 0 ) {
            abbrevCnt++;        /* gets subtracted by IMBackSpace */
        }
    }
    return( IMBackSpace() );

} /* IMDelete */
Exemple #5
0
/*
 * DeleteBlockFromCurrentLine - remove chars from line, leave result in work line
 */
vi_rc DeleteBlockFromCurrentLine( int scol, int ecol, int saveb_flag )
{
    int i;

    /*
     * check if we can do this on the current line
     */
    if( scol > ecol ) {
        i = scol;
        scol = ecol;
        ecol = i;
    }
    if( scol < 0 || ecol >= CurrentLine->len ) {
        return( ERR_CANNOT_DELETE_CHAR );
    }

    if( saveb_flag ) {
        AddLineToSavebuf( CurrentLine->data, scol, ecol );
    }

    /*
     * remove chars
     */
    GetCurrentLine();
    for( i = ecol + 1; i <= CurrentLine->len; i++ ) {
        WorkLine->data[scol + (i - (ecol + 1))] = WorkLine->data[i];
    }
    WorkLine->len -= ecol - scol + 1;
    return( ERR_NO_ERR );

} /* DeleteBlockFromCurrentLine */
Exemple #6
0
static void OldStyleComment (void)
/* Remove an old style C comment from line. */
{
    /* Remember the current line number, so we can output better error
     * messages if the comment is not terminated in the current file.
     */
    unsigned StartingLine = GetCurrentLine();

    /* Skip the start of comment chars */
    NextChar ();
    NextChar ();

    /* Skip the comment */
    while (CurC != '*' || NextC != '/') {
        if (CurC == '\0') {
            if (NextLine () == 0) {
                PPError ("End-of-file reached in comment starting at line %u",
                         StartingLine);
                return;
            }
        } else {
            if (CurC == '/' && NextC == '*') {
                PPWarning ("`/*' found inside a comment");
            }
            NextChar ();
        }
    }

    /* Skip the end of comment chars */
    NextChar ();
    NextChar ();
}
Exemple #7
0
void
clrtoeol(void)
{
    register screenline_t *slp = GetCurrentLine();
    register int    ln;

    standing = NA;

    if (cur_col <= slp->sso)
	slp->mode &= ~STANDOUT;

    /*
    if (cur_col == 0) // TODO and contains ANSI
    {
	// workaround poor ANSI issue
	size_t sz = (slp->len > slp->oldlen) ? slp->len : slp->oldlen;
	sz = (sz < ANSILINELEN) ? sz : ANSILINELEN;
	memset(slp->data, ' ', sz);
	slp->len = 0;
	return;
    }
    */

    if (cur_col > slp->oldlen) {
	for (ln = slp->len; ln <= cur_col; ln++)
	    slp->data[ln] = ' ';
    }
    if (cur_col < slp->oldlen) {
	for (ln = slp->len; ln >= cur_col; ln--)
	    slp->data[ln] = ' ';
    }
    slp->len = cur_col;
}
Exemple #8
0
	/// Indent if newline was added.
	void OnCharAdded(wxScintillaEvent &event) {
		// Change this if support for mac files with \r is needed
		if (event.GetKey() == '\n' || event.GetKey() == '\r') {
			int currentLine = GetCurrentLine();
			if (currentLine <= 0) {
				return;
			}

			// width of one indent character
			int indentWidth = (GetUseTabs() ? GetTabWidth() : 1);
			if (indentWidth == 0) {
				return;
			}

			// indent as prev line level
			int indentSize = GetLineIndentation(currentLine - 1);
			SetLineIndentation(currentLine, indentSize);

			// position = (line start pos) + (tabs count) + (space count)
			GotoPos(PositionFromLine(currentLine)
				+ (indentSize / indentWidth)
				+ (indentSize % indentWidth));

			// notify that the text was changed
			ChangeModified(true);
		}
	}
Exemple #9
0
void Internal (const char* Format, ...)
/* Print a message about an internal compiler error and die. */
{
    va_list ap;

    const char* FileName;
    unsigned    LineNum;
    if (CurTok.LI) {
     	FileName = GetInputName (CurTok.LI);
     	LineNum  = GetInputLine (CurTok.LI);
    } else {
     	FileName = GetCurrentFile ();
     	LineNum  = GetCurrentLine ();
    }

    fprintf (stderr, "%s(%u): Internal compiler error:\n",
     	     FileName, LineNum);

    va_start (ap, Format);
    vfprintf (stderr, Format, ap);
    va_end (ap);
    fprintf (stderr, "\n");

    if (Line) {
        fprintf (stderr, "\nInput: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
    }

    /* Use abort to create a core dump */
    abort ();
}
Exemple #10
0
void Fatal (const char* Format, ...)
/* Print a message about a fatal error and die */
{
    va_list ap;

    const char* FileName;
    unsigned    LineNum;
    if (CurTok.LI) {
     	FileName = GetInputName (CurTok.LI);
     	LineNum  = GetInputLine (CurTok.LI);
    } else {
     	FileName = GetCurrentFile ();
     	LineNum  = GetCurrentLine ();
    }

    fprintf (stderr, "%s(%u): Fatal: ", FileName, LineNum);

    va_start (ap, Format);
    vfprintf (stderr, Format, ap);
    va_end (ap);
    fprintf (stderr, "\n");

    if (Line) {
        Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
    }
    exit (EXIT_FAILURE);
}
Exemple #11
0
/* TextEditor::onCharAdded
 * Called when a character is added to the text
 *******************************************************************/
void TextEditor::onCharAdded(wxStyledTextEvent& e)
{
	// Update line numbers margin width
	string numlines = S_FMT("0%d", GetNumberOfLines());
	SetMarginWidth(0, TextWidth(wxSTC_STYLE_LINENUMBER, numlines));

	// Auto indent
	int currentLine = GetCurrentLine();
	if (txed_auto_indent && e.GetKey() == '\n')
	{
		// Get indentation amount
		int lineInd = 0;
		if (currentLine > 0)
			lineInd = GetLineIndentation(currentLine - 1);

		// Do auto-indent if needed
		if (lineInd != 0)
		{
			SetLineIndentation(currentLine, lineInd);

			// Skip to end of tabs
			while (1)
			{
				int chr = GetCharAt(GetCurrentPos());
				if (chr == '\t' || chr == ' ')
					GotoPos(GetCurrentPos()+1);
				else
					break;
			}
		}
	}

	// The following require a language to work
	if (language)
	{
		// Call tip
		if (e.GetKey() == '(' && txed_calltips_parenthesis)
		{
			openCalltip(GetCurrentPos());
		}

		// End call tip
		if (e.GetKey() == ')')
		{
			CallTipCancel();
		}

		// Comma, possibly update calltip
		if (e.GetKey() == ',' && txed_calltips_parenthesis)
		{
			//openCalltip(GetCurrentPos());
			//if (CallTipActive())
			updateCalltip();
		}
	}

	// Continue
	e.Skip();
}
Exemple #12
0
void PPError (const char* Format, ...)
/* Print an error message. For use within the preprocessor.  */
{
    va_list ap;
    va_start (ap, Format);
    IntError (GetCurrentFile(), GetCurrentLine(), Format, ap);
    va_end (ap);
}
Exemple #13
0
void PPWarning (const char* Format, ...)
/* Print warning message. For use within the preprocessor. */
{
    va_list ap;
    va_start (ap, Format);
    IntWarning (GetCurrentFile(), GetCurrentLine(), Format, ap);
    va_end (ap);
}
Exemple #14
0
bool wxSTEditorShell::CaretOnPromptLine(STE_CaretPos_Type option)
{
    int prompt_line = GetPromptLine();
    bool on_last    = GetCurrentLine() >= prompt_line;

    //wxPrintf(wxT("Caret on last line total %d current %d onlast %d\n"), total_lines, GetCurrentLine(), (int)on_last);

    if (!on_last && (option != STE_CARET_MOVE_NONE))
    {
        if ((option & STE_CARET_MOVE_LASTLINE) != 0)
            GotoLine(prompt_line);
        else if ((option & STE_CARET_MOVE_ENDTEXT) != 0)
            GotoPos(GetLength());
    }

    return GetCurrentLine() >= prompt_line;
}
Exemple #15
0
/*
 * IMBackSpace - process the backspace key in insert mode
 */
vi_rc IMBackSpace( void )
{
    char        killedChar, overChar;
    bool        mv_right;
    bool        stay_at_end;
    int         i;

    if( CurrentFile == NULL ) {
        return( ERR_NO_FILE );
    }

    startNewLineUndo();
    if( abbrevCnt > 0 ) {
        abbrevCnt--;
    }
    if( CurrentPos.column == 1 ) {

        if( !EditFlags.WrapBackSpace ) {
            return( ERR_NO_ERR );
        }
        if( CurrentPos.line ==1 ) {
            return( ERR_NO_ERR );
        }
        stay_at_end = FALSE;
        if( WorkLine->len == 0 ) {
            stay_at_end = TRUE;
        }
        doneWithCurrentLine();
        abbrevCnt = 0;
        GoToLineRelCurs( CurrentPos.line - 1 );
        GoToColumnOnCurrentLine( CurrentLine->len );
        mv_right = TRUE;
        if( CurrentLine->len == 0 ) {
            mv_right = FALSE;
        }
        GenericJoinCurrentLineToNext( FALSE );
        if( mv_right && !stay_at_end ) {
            GoToColumnOnCurrentLine( CurrentPos.column + 1 );
        }
        if( stay_at_end ) {
            GoToColumnOK( CurrentLine->len + 1 );
        }
        CurrentLineReplaceUndoStart();
        currLineRepUndo = TRUE;
        GetCurrentLine();
        return( ERR_NO_ERR );
    }
    killedChar = WorkLine->data[CurrentPos.column - 2];
    overChar = WorkLine->data[CurrentPos.column - 1];
    for( i = CurrentPos.column - 1; i <= WorkLine->len + 1; i++ ) {
        WorkLine->data[i - 1] = WorkLine->data[i];
    }
    WorkLine->len--;
    GoToColumn( CurrentPos.column - 1, WorkLine->len + 1 );
    DisplayWorkLine( SSKillsFlags( killedChar ) || SSKillsFlags( overChar ) );
    return( ERR_NO_ERR );

} /* IMBackSpace */
Exemple #16
0
/*
 * EnterHexKey - enter a hexidecimal key stroke and insert it into the text
 */
vi_rc EnterHexKey( void )
{
    int         i;
    char        st[MAX_STR], val;
    vi_rc       rc;
    const char  *ptr;

    rc = ModificationTest();
    if( rc != ERR_NO_ERR ) {
        return( rc );
    }
    if( CurrentLine->len >= EditVars.MaxLine - 1 ) {
        return( ERR_LINE_FULL );
    }

    rc = PromptForString( "Enter the number of char to insert:", st, sizeof( st ) - 1, NULL );
    if( rc != ERR_NO_ERR ) {
        if( rc == NO_VALUE_ENTERED ) {
            return( ERR_NO_ERR );
        }
        return( rc );
    }

    /*
     * get value
     */
    ptr = SkipLeadingSpaces( st );
    val = (char)strtol( ptr, NULL, 0 );
    if( val == '\0' ) {
        return( ERR_INVALID_VALUE );
    }

    /*
     * build undo record
     */
    StartUndoGroup( UndoStack );
    CurrentLineReplaceUndoStart();
    CurrentLineReplaceUndoEnd( true );
    EndUndoGroup( UndoStack );

    /*
     * add the char
     */
    GetCurrentLine();
    for( i = WorkLine->len; i >= CurrentPos.column - 1; i-- ) {
        WorkLine->data[i + 1] = WorkLine->data[i];
    }
    WorkLine->data[CurrentPos.column - 1] = val;
    WorkLine->len++;
    DisplayWorkLine( true );
    if( CurrentPos.column < WorkLine->len ) {
        GoToColumn( CurrentPos.column + 1, WorkLine->len + 1 );
    }
    ReplaceCurrentLine();
    EditFlags.Dotable = true;
    return( ERR_NO_ERR );

} /* EnterHexKey */
Exemple #17
0
void LLDBPlugin::OnJumpToCursor(wxCommandEvent& event)
{
    CHECK_IS_LLDB_SESSION();

    const auto editor = m_mgr->GetActiveEditor();
    if(!editor) { return; }

    m_connector.JumpTo(editor->GetFileName(), editor->GetCurrentLine() + 1);
}
Exemple #18
0
/*
 * startNewLineUndo - start current line undo stuff
 */
static void startNewLineUndo( void )
{
    if( needNewUndoForLine ) {
        CurrentLineReplaceUndoStart();
        currLineRepUndo = TRUE;
        GetCurrentLine();
        needNewUndoForLine = FALSE;
    }

} /* startNewLineUndo */
Exemple #19
0
void CodeEditor::OnCharAdded(wxScintillaEvent &event)
{
	char ch = event.GetKey();
	int currentLine = GetCurrentLine();
	int pos = GetCurrentPos();

	if (ch == wxT('\n') && currentLine > 0)
	{
		BeginUndoAction();

		wxString indent = GetLineIndentString(currentLine - 1);

		wxChar b = GetLastNonWhitespaceChar();
		if(b == wxT('{'))
		{
			if(GetUseTabs())
				indent << wxT("\t");
			else
				indent << wxT("    ");
		}

		InsertText(pos, indent);
		GotoPos((int)(pos + indent.Length()));
		ChooseCaretX();

		EndUndoAction();
	}
	else if(ch == wxT('}'))
	{
		BeginUndoAction();

		wxString line = GetLine(currentLine);
		line.Trim(false);
		line.Trim(true);
		if(line.Matches(wxT("}")))
		{
			pos = GetCurrentPos() - 2;
			pos = FindBlockStart(pos, wxT('{'), wxT('}'));

			if(pos != -1)
			{
				wxString indent = GetLineIndentString(LineFromPosition(pos));
				indent << wxT('}');
				DelLineLeft();
				DelLineRight();
				pos = GetCurrentPos();
				InsertText(pos, indent);
				GotoPos((int)(pos + indent.Length()));
				ChooseCaretX();
			}
		}

		EndUndoAction();
	}
}
Exemple #20
0
// readback
int		
instr(char *str)
{
    register screenline_t *slp = GetCurrentLine();
    *str = 0;
    if (!slp)
	return 0;
    slp->data[slp->len] = 0;
    strip_ansi(str, (char*)slp->data, STRIP_ALL);
    return strlen(str);
}
Exemple #21
0
int	
inansistr(char *str, int n)
{
    register screenline_t *slp = GetCurrentLine();
    *str = 0;
    if (!slp)
	return 0;
    slp->data[slp->len] = 0;
    strlcpy(str, (char*)slp->data, n);
    return strlen(str);
}
Exemple #22
0
void CodeEdit::OnCharAdded(wxStyledTextEvent& event)
{

    // Indent the line to the same indentation as the previous line.
    // Adapted from http://STCntilla.sourceforge.net/STCntillaUsage.html

    char ch = event.GetKey();

    if  (ch == '\r' || ch == '\n')
    {

        int line        = GetCurrentLine();
        int lineLength  = LineLength(line);

        if (line > 0 && lineLength <= 2)
        {

            wxString buffer = GetLine(line - 1);
                
            for (unsigned int i =  0; i < buffer.Length();  ++i)
            {
                if (buffer[i] != ' ' && buffer[i] != '\t')
                {
                    buffer.Truncate(i);
                    break;
                }
            }

            ReplaceSelection(buffer);
            
            // Remember that we just auto-indented so that the backspace
            // key will un-autoindent us.
            m_autoIndented = true;
            
        }
        
    }
    else if (m_enableAutoComplete && m_autoCompleteManager != NULL)
    {

        // Handle auto completion.

        wxString token;
        
        if (GetTokenFromPosition(GetCurrentPos() - 1, ".:", token))
        {
            StartAutoCompletion(token);
        }

    }

    event.Skip();

}
Exemple #23
0
/*
 * SplitUpLine - split up a line with SPLIT_CHAR's in them
 */
linenum SplitUpLine( linenum cl )
{
    linenum     extra = 0;
    int         j, i, k;
    char        *buff;

    /*
     * run through, and for every 0x01, make a new line
     */
    for( ;; ) {

        /*
         * get current line
         */
        CurrentPos.line = cl + extra;
        CGimmeLinePtr( CurrentPos.line, &CurrentFcb, &CurrentLine );
        GetCurrentLine();

        for( i = 0; i <= WorkLine->len; i++ ) {
            /*
             * found a place to split.  make this line shorter,
             * and create a new line with the rest of the data
             * for this line
             */
            if( WorkLine->data[i] == SPLIT_CHAR ) {
                buff = StaticAlloc();
                k = 0;
                for( j = i + 1; j <= WorkLine->len; j++ ) {
                    buff[k++] = WorkLine->data[j];
                }
                WorkLine->data[i] = 0;
                WorkLine->len = i;
                ReplaceCurrentLine();
                AddNewLineAroundCurrent( buff, k - 1, INSERT_AFTER );
                extra++;
                StaticFree( buff );
                break;
            }

            /*
             * at the very end, undo what we did and go back
             */
            if( WorkLine->data[i] == 0 ) {
                ReplaceCurrentLine();
                UndoInsert( cl + 1, cl + extra, UndoStack );
                return( extra );
            }
        }
    }

} /* SplitUpLine */
Exemple #24
0
int		
innstr(char *str, int n)
{
    register screenline_t *slp = GetCurrentLine();
    char buf[ANSILINELEN];
    *str = 0;
    if (!slp)
	return 0;
    slp->data[slp->len] = 0;
    strip_ansi(buf, (char*)slp->data, STRIP_ALL);
    buf[ANSILINELEN-1] = 0;
    strlcpy(str, buf, n);
    return strlen(str);
}
Exemple #25
0
void Edit::OnCharAdded(wxStyledTextEvent &event) {
  event.Skip();
  
  const wxChar c = event.GetKey();
  if (c == wxT('\n')) {
    const int line = GetCurrentLine();
    const int indent = line < 1 ? 0 : GetLineIndentation(line - 1);

    if (indent != 0) {
      SetLineIndentation(line, indent);
      GotoPos(GetLineIndentPosition(line));
    }
  }
}
Exemple #26
0
void Edit::OnCharAdded (wxStyledTextEvent &event) {
    char chr = (char)event.GetKey();
    int currentLine = GetCurrentLine();
    // Change this if support for mac files with \r is needed
    if (chr == '\n') {
        int lineInd = 0;
        if (currentLine > 0) {
            lineInd = GetLineIndentation(currentLine - 1);
        }
        if (lineInd == 0) return;
        SetLineIndentation (currentLine, lineInd);
        GotoPos(PositionFromLine (currentLine) + lineInd);
    }
}
Exemple #27
0
void IWnd_stc::OnCharAdded (wxStyledTextEvent &evt)
{
	char chr = (char)evt.GetKey();
	if (chr == '\n')
	{
		int currentLine = GetCurrentLine();
		if (currentLine < 1) return;

		int lineInd = GetLineIndentation(currentLine - 1);
		if (lineInd == 0) return;

		SetLineIndentation (currentLine, lineInd);
		GotoPos(GetLineIndentPosition(currentLine));
	}

}
Exemple #28
0
/*
 * continueInsertText - continue in insert mode after mouse events
 */
static void continueInsertText( int col, bool overstrike )
{
    overStrike = overstrike;
    abbrevCnt = 0;
    if( !EditFlags.Modeless ) {
        UpdateEditStatus();
    }
    EditFlags.Dotable = TRUE;
    EditFlags.NoReplaceSearchString = TRUE;
    EditFlags.InsertModeActive = TRUE;
    if( col > 1 && CurrentLine->len == 0 ) {
        col = 1;
    }
    GoToColumnOK( col );
    GetCurrentLine();

} /* continueInsertText */
Exemple #29
0
void Navigator::SyncLines()
{
	if(IsNull(theide->editfile) || navigating)
		return;
	int ln = GetCurrentLine() + 1;
	int fi = GetSourceFileIndex(theide->editfile);
	int q = -1;
	for(int i = 0; i < navlines.GetCount(); i++) {
		const NavLine& l = navlines.Get(i, 0).To<NavLine>();
		if(l.file == fi && l.line <= ln && i < navlines.GetCount())
			q = i;
	}
	if(dlgmode)
		navlines.GoBegin();
	else
	if(q >= 0)
		navlines.SetCursor(q);
}
Exemple #30
0
void Edit::OnAnnotationAdd(wxCommandEvent& WXUNUSED(event))
{
    const int line = GetCurrentLine();

    wxString ann = AnnotationGetText(line);
    ann = wxGetTextFromUser
          (
            wxString::Format("Enter annotation for the line %d", line),
            "Edit annotation",
            ann,
            this
          );
    if ( ann.empty() )
        return;

    AnnotationSetText(line, ann);
    AnnotationSetStyle(line, ANNOTATION_STYLE);

    // Scintilla doesn't update the scroll width for annotations, even with
    // scroll width tracking on, so do it manually.
    const int width = GetScrollWidth();

    // NB: The following adjustments are only needed when using
    //     wxSTC_ANNOTATION_BOXED annotations style, but we apply them always
    //     in order to make things simpler and not have to redo the width
    //     calculations when the annotations visibility changes. In a real
    //     program you'd either just stick to a fixed annotations visibility or
    //     update the width when it changes.

    // Take into account the fact that the annotation is shown indented, with
    // the same indent as the line it's attached to.
    int indent = GetLineIndentation(line);

    // This is just a hack to account for the width of the box, there doesn't
    // seem to be any way to get it directly from Scintilla.
    indent += 3;

    const int widthAnn = TextWidth(ANNOTATION_STYLE, ann + wxString(indent, ' '));

    if (widthAnn > width)
        SetScrollWidth(widthAnn);
}