Esempio n. 1
0
void ClangPlugin::DoAutocomplete(const CCToken& token, cbEditor* ed)
{
#ifdef CLANGPLUGIN_TRACE_FUNCTIONS
    fprintf(stdout,"%s\n", __PRETTY_FUNCTION__);
#endif
    wxString tknText = token.name;
    int idx = tknText.Find(wxT(':'));
    if (idx != wxNOT_FOUND)
        tknText.Truncate(idx);
    std::pair<int, int> offsets = std::make_pair(0, 0);
    cbStyledTextCtrl* stc = ed->GetControl();
    wxString suffix = m_Proxy.GetCCInsertSuffix(m_TranslUnitId, token.id,
            GetEOLStr(stc->GetEOLMode())
            + ed->GetLineIndentString(stc->GetCurrentLine()),
            offsets);

    int pos = stc->GetCurrentPos();
    int startPos = std::min(stc->WordStartPosition(pos, true), std::min(stc->GetSelectionStart(),
            stc->GetSelectionEnd()));
    int moveToPos = startPos + tknText.Length();
    stc->SetTargetStart(startPos);
    int endPos = stc->WordEndPosition(pos, true);
    if (tknText.EndsWith(stc->GetTextRange(pos, endPos)))
    {
        if (!suffix.IsEmpty())
        {
            if (stc->GetCharAt(endPos) == (int)suffix[0])
            {
                if (suffix.Length() != 2 || stc->GetCharAt(endPos + 1) != (int)suffix[1])
                    offsets = std::make_pair(1, 1);
            }
            else
                tknText += suffix;
        }
    }
    else
    {
        endPos = pos;
        tknText += suffix;
    }
    stc->SetTargetEnd(endPos);

    stc->AutoCompCancel(); // so (wx)Scintilla does not insert the text as well

    if (stc->GetTextRange(startPos, endPos) != tknText)
        stc->ReplaceTarget(tknText);
    stc->SetSelectionVoid(moveToPos + offsets.first, moveToPos + offsets.second);
    stc->ChooseCaretX();
    if (token.category != tcLangKeyword
            && (offsets.first != offsets.second || offsets.first == 1))
    {
        int tooltipMode = Manager::Get()->GetConfigManager(wxT("ccmanager"))->ReadInt(wxT("/tooltip_mode"), 1);
        if (tooltipMode != 3) // keybound only
        {
            CodeBlocksEvent evt(cbEVT_SHOW_CALL_TIP);
            Manager::Get()->ProcessEvent(evt);
        }
    }
}
void ClassWizardDlg::OnOKClick(wxCommandEvent& WXUNUSED(event))
{
    // Reset
    m_Header         = XRCCTRL(*this, "txtHeader", wxTextCtrl)->GetValue();
    m_Implementation = XRCCTRL(*this, "txtImplementation", wxTextCtrl)->GetValue();

    // obtain variable for easy reference
    m_Name      = XRCCTRL(*this, "txtName", wxTextCtrl)->GetValue();
    m_Arguments = XRCCTRL(*this, "txtArguments", wxTextCtrl)->GetValue();
    // Error check
    if (m_Name.IsEmpty())
    {
        cbMessageBox(_T("Please specify a class name to continue."),
                     _T("Error"), wxOK | wxICON_ERROR, this);
        return;
    }
    // Extract namespaces from class name
    wxStringTokenizer tkz(m_Name, _T("::"));
    m_Name = wxEmptyString;
    while ( tkz.HasMoreTokens() )
    {
        // Store the old "class name" as (another) namespace
        if (!m_Name.IsEmpty())
        {
            m_NameSpaces.Add(m_Name);
        }
        // Stor the new "class name" as true class name
        m_Name = tkz.GetNextToken();
    }

    m_HasDestructor     = XRCCTRL(*this, "chkHasDestructor", wxCheckBox)->GetValue();
    m_VirtualDestructor = XRCCTRL(*this, "chkVirtualDestructor", wxCheckBox)->GetValue();
    m_HasCopyCtor       = XRCCTRL(*this, "chkHasCopyCtor", wxCheckBox)->GetValue();
    m_HasAssignmentOp   = XRCCTRL(*this, "chkHasAssignmentOp", wxCheckBox)->GetValue();
    if (!m_HasDestructor)
    {
        m_VirtualDestructor = false; // Fix error
    }

    m_Inherits         = XRCCTRL(*this, "chkInherits", wxCheckBox)->GetValue();
    m_Ancestor         = XRCCTRL(*this, "txtInheritance", wxTextCtrl)->GetValue();
    m_AncestorFilename = XRCCTRL(*this, "txtInheritanceFilename", wxTextCtrl)->GetValue();
    m_AncestorScope    = XRCCTRL(*this, "cmbInheritanceScope", wxComboBox)->GetValue();
    if (m_Ancestor.IsEmpty())
        m_Inherits = false; // Fix error

    m_Documentation = XRCCTRL(*this, "chkDocumentation", wxCheckBox)->GetValue();

    m_AddPathToProject = XRCCTRL(*this, "chkAddPathToProject", wxCheckBox)->GetValue();
    m_UseRelativePath  = XRCCTRL(*this, "chkRelativePath", wxCheckBox)->GetValue();
    m_CommonDir        = XRCCTRL(*this, "chkCommonDir", wxCheckBox)->GetValue();
    if (m_CommonDir)
    {
        m_IncludeDir = XRCCTRL(*this, "txtCommonDir", wxTextCtrl)->GetValue();
        m_ImplDir    = XRCCTRL(*this, "txtCommonDir", wxTextCtrl)->GetValue();
    }
    else
    {
        m_IncludeDir = XRCCTRL(*this, "txtIncludeDir", wxTextCtrl)->GetValue();
        m_ImplDir    = XRCCTRL(*this, "txtImplDir", wxTextCtrl)->GetValue();
    }

    m_GuardBlock = XRCCTRL(*this, "chkGuardBlock", wxCheckBox)->GetValue();
    m_GuardWord  = XRCCTRL(*this, "txtGuardBlock", wxTextCtrl)->GetValue();
    if (m_GuardWord.IsEmpty())
    {
        m_GuardBlock = false; // Fix error
    }

    m_GenerateImplementation = XRCCTRL(*this, "chkImplementation", wxCheckBox)->GetValue();
    m_HeaderInclude          = XRCCTRL(*this, "txtHeaderInclude", wxTextCtrl)->GetValue();

    // Common stuff
    bool usestabs = Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/use_tab"),    false);
    int  tabsize  = Manager::Get()->GetConfigManager(_T("editor"))->ReadInt(_T("/tab_size"),    4);

    m_TabStr = usestabs ? wxString(_T("\t")) : wxString(_T(' '), tabsize);
    m_EolStr = GetEOLStr();

    // actual file creation starts here
    bool success = DoHeader();
    if (success)
    {
        if (m_GenerateImplementation)
            success = DoImpl();
    }

    if (success)
        EndModal(wxID_OK);
}
void SmartIndentCpp::DoBraceCompletion(cbStyledTextCtrl* control, const wxChar& ch)const
{
    int pos = control->GetCurrentPos();
    int style = control->GetStyleAt(pos);

    // match preprocessor commands
    if ( (ch == _T('\n')) || ( (control->GetEOLMode() == wxSCI_EOL_CR) && (ch == _T('\r')) ) )
    {
        wxRegEx ppIf(wxT("^[ \t]*#[ \t]*if"));
        wxRegEx ppElse(wxT("^[ \t]*#[ \t]*el"));
        wxRegEx ppEnd(wxT("^[ \t]*#[ \t]*endif"));
        wxRegEx pp(wxT("^([ \t]*#[ \t]*)[a-z]*([ \t]+([a-zA-Z0-9_]+)|())")); // generic match to extract parts
        const int ppLine = control->GetCurrentLine() - 1;
        if (ppIf.Matches(control->GetLine(ppLine)) || ppElse.Matches(control->GetLine(ppLine)))
        {
            int depth = 1;
            for (int i = ppLine + 1; i < control->GetLineCount(); ++i)
            {
                if (control->GetLine(i).Find(wxT('#')) != wxNOT_FOUND) // limit testing due to performance cost
                {
                    if (ppIf.Matches(control->GetLine(i))) // ignore else's, elif's, ...
                        ++depth;
                    else if (ppEnd.Matches(control->GetLine(i)))
                        --depth;
                }
                if (depth == 0)
                    break;
            }
            if (depth > 0)
            {
                wxString endIf = wxT("endif");
                if (pp.Matches(control->GetLine(ppLine)))
                {
                    endIf.Prepend(pp.GetMatch(control->GetLine(ppLine), 1));
                    if (!pp.GetMatch(control->GetLine(ppLine), 3).IsEmpty())
                        endIf.Append(wxT(" // ") + pp.GetMatch(control->GetLine(ppLine), 3));
                }
                else
                    endIf.Prepend(wxT("#"));
                control->InsertText(pos, GetEOLStr(control->GetEOLMode()) + endIf);
                return;
            }
        }
    }

    if ( control->IsComment(style) || control->IsPreprocessor(style) )
        return;
    if (ch == _T('\'') || ch == _T('"'))
    {
        if (   (control->GetCharAt(pos) == ch)
            && (control->GetCharAt(pos - 2) != _T('\\')) )
        {
            control->DeleteBack();
            control->GotoPos(pos);
        }
        else
        {
            const wxChar left = control->GetCharAt(pos - 2);
            const wxChar right = control->GetCharAt(pos);
            if (   control->IsCharacter(style)
                || control->IsString(style)
                || left == _T('\\')
                || (   (left > _T(' '))
                    && (left != _T('('))
                    && (left != _T('=')) )
                || (   (right > _T(' '))
                    && (right != _T(')')) ) )
            {
                return;
            }
            control->AddText(ch);
            control->GotoPos(pos);
        }
        return;
    }
    if ( control->IsCharacter(style) || control->IsString(style) )
        return;
    const wxString leftBrace(_T("([{"));
    const wxString rightBrace(_T(")]}"));
    int index = leftBrace.Find(ch);
    const wxString unWant(_T(");\n\r\t\b "));
    const wxChar nextChar = control->GetCharAt(pos);
    #if wxCHECK_VERSION(2, 9, 0)
    if ((index != wxNOT_FOUND) && ((unWant.Find(wxUniChar(nextChar)) != wxNOT_FOUND) || (pos == control->GetLength())))
    #else
    if ((index != wxNOT_FOUND) && ((unWant.Find(nextChar) != wxNOT_FOUND) || (pos == control->GetLength())))
    #endif
    {
        control->AddText(rightBrace.GetChar(index));
        control->GotoPos(pos);
        if (ch == _T('{'))
        {
            const int curLine = control->GetCurrentLine();
            int keyLine = curLine;
            wxString text;
            do
            {
                int keyPos = control->GetLineIndentPosition(keyLine);
                int start = control->WordStartPosition(keyPos, true);
                int end = control->WordEndPosition(keyPos, true);
                text = control->GetTextRange(start, end);
            }
            while (   (text.IsEmpty() || text == _T("public") || text == _T("protected") || text == _T("private"))
                   && (text != _T("namespace"))
                   && (--keyLine >= 0) );

            if (text == _T("class") || text == _T("struct") || text == _T("enum") || text == _T("union"))
                control->InsertText(control->GetLineEndPosition(curLine), _T(";"));

            const wxRegEx reg(_T("^[ \t]*{}[ \t]*"));
            if (reg.Matches(control->GetCurLine()))
            {
                control->NewLine();
                control->GotoPos(pos);
                control->NewLine();
                return;
            }
        }
    }
    else
    {
        index = rightBrace.Find(ch);
        if (index != wxNOT_FOUND)
        {
            if (control->GetCharAt(pos) == ch)
            {
                control->DeleteBack();
                control->GotoPos(pos);
                return;
            }
        }
    }
}
Esempio n. 4
0
void ToDoList::OnAddItem(cb_unused wxCommandEvent& event)
{
    cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
    if (!ed)
        return;

    EditorColourSet* colour_set = Manager::Get()->GetEditorManager()->GetColourSet();
    if (!colour_set)
        return;

    HighlightLanguage hlang = colour_set->GetLanguageName(ed->GetLanguage());
    bool edIsCCpp = (hlang == _T("C/C++"));

    CommentToken token = colour_set->GetCommentToken(ed->GetLanguage());
    bool hasStreamComments = not token.streamCommentStart.IsEmpty();
    bool hasLineComments = not token.lineComment.IsEmpty();

    if (!(edIsCCpp||hasLineComments||hasStreamComments))
        return;
    std::bitset<(int)tdctError+1> supportedTdcts;
    supportedTdcts[tdctLine] = !(token.lineComment.IsEmpty());
    supportedTdcts[tdctStream] = !(token.streamCommentStart.IsEmpty());
    supportedTdcts[tdctDoxygenLine] = !(token.doxygenLineComment.IsEmpty());
    supportedTdcts[tdctDoxygenStream] = !(token.doxygenStreamCommentStart.IsEmpty());
    supportedTdcts[tdctWarning] = edIsCCpp;
    supportedTdcts[tdctError] = edIsCCpp;
    // display todo dialog
    AddTodoDlg dlg(Manager::Get()->GetAppWindow(), m_Users, m_Types, supportedTdcts );
    PlaceWindow(&dlg);
    if (dlg.ShowModal() != wxID_OK)
        return;
    // Re-load users and types as they might have changed by the user via AddTodoDlg
    LoadUsers();
    LoadTypes();

    cbStyledTextCtrl* control = ed->GetControl();

    // calculate insertion point
    int idx = 0;
    int crlfLen = 0; // length of newline chars
    int origPos = control->GetCurrentPos(); // keep current position in the document
    int line = control->GetCurrentLine(); // current line
    ToDoCommentType CmtType = dlg.GetCommentType();
    if (dlg.GetPosition() == tdpCurrent)
    {
        idx = control->GetCurrentPos(); // current position in the document
        // if the style is cpp comments (// ...), there's the possibility that the current position
        // is somewhere in the middle of a line of code; this would result
        // in everything after the insertion point to turn into comments
        // let's double check this with the user
        if (idx != control->GetLineEndPosition(line) && (CmtType != tdctStream) && (CmtType != tdctDoxygenStream))
        {
            // let's ask the user, and present as options
            // keep cpp style at current position, switch to c style, add the todo at the end (keeping cpp style)
            // if user cancels out / do nothing : just return
            // future idea : check if there's any non white space character
            // if yes -> in the middle of code
            // if no -> then only whitespace after the insertion point -> no harm to turn that into comments
            wxString streamStart = token.streamCommentStart, streamEnd = token.streamCommentEnd;
            if (CmtType == tdctDoxygenLine && !token.doxygenStreamCommentStart.IsEmpty())
            {
                streamStart = token.doxygenStreamCommentStart;
                streamEnd = token.doxygenStreamCommentEnd;
            }
            AskTypeDlg asktype_dlg(Manager::Get()->GetAppWindow(), streamStart, streamEnd);
            PlaceWindow(&asktype_dlg);
            if (asktype_dlg.ShowModal() != wxID_OK)
                return;
            switch(asktype_dlg.GetTypeCorrection())
            {
                case tcStay:
                    break; // do nothing, leave things as they are
                case tcSwitch:
                    if (CmtType == tdctDoxygenLine)
                        CmtType = tdctDoxygenStream;
                    else
                        CmtType = tdctStream;
                    break;
                case tcMove:
                default:
                    idx = control->GetLineEndPosition(line);
                    break;
            } // end switch
        }
    }
    else
    {
        if      (dlg.GetPosition() == tdpAbove)
            idx = control->GetLineEndPosition(line - 1); // get previous line's end
        else if (dlg.GetPosition() == tdpBelow)
            idx = control->GetLineEndPosition(line); // get current line's end
        // calculate insertion point by skipping next newline
        switch (control->GetEOLMode())
        {
            case wxSCI_EOL_CRLF: crlfLen = 2; break;
            case wxSCI_EOL_CR: // fall-though
            case wxSCI_EOL_LF: // fall-though
            default:             crlfLen = 1; break;
        }
        if (idx > 0)
            idx += crlfLen;
    }
    // make sure insertion point is valid (bug #1300981)
    if (idx > control->GetLength())
        idx = control->GetLength();

    // ok, construct todo line text like this:
    // TODO (mandrav#0#): Implement code to do this and the other...
    wxString buffer;

    // start with the comment
    switch(CmtType)
    {
        default:
        case tdctLine:
            buffer << token.lineComment;
            break;
        case tdctDoxygenLine:
            buffer << token.doxygenLineComment;
            break;
        case tdctDoxygenStream:
            buffer << token.doxygenStreamCommentStart;
            break;
        case tdctWarning:
            buffer << _T("#warning");
            break;
        case tdctError:
            buffer << _T("#error");
            break;
        case tdctStream:
            buffer << token.streamCommentStart;
            break;
    } // end switch
    buffer << _T(" ");

    // continue with the type
    buffer << dlg.GetType() << _T(" ");
    wxString priority = wxString::Format(_T("%d"), dlg.GetPriority()); // do it like this (wx bug with int and streams)

    // now do the () part
    buffer << _T("(") << dlg.GetUser() << _T("#") << priority << _T("#") << (dlg.DateRequested() ? (wxDateTime::Today().Format(_T("%x): "))) :  _T("): "));

    wxString text = dlg.GetText();

    // make sure that multi-line notes, don't break the todo
    if ( (CmtType == tdctWarning) || (CmtType == tdctError) )
    {
        if (text.Replace(_T("\r\n"), _T("\\\r\n")) == 0)
            text.Replace(_T("\n"), _T("\\\n"));
        // now see if there were already a backslash before newline
        if (text.Replace(_T("\\\\\r\n"), _T("\\\r\n")) == 0)
            text.Replace(_T("\\\\\n"), _T("\\\n"));
    }
    else if (CmtType == tdctLine || (CmtType == tdctDoxygenLine))
    {
        wxString lc;
        if (CmtType == tdctLine)
            lc = token.lineComment;
        else
            lc = token.doxygenLineComment;
        // comment every line from the todo text
        if ( text.Replace(_T("\r\n"), _T("\r\n")+lc) == 0 )
            text.Replace(_T("\n"), _T("\n")+lc);
        // indicate (on the first line) that there is some more text
        if ( text.Replace(_T("\r\n"), _T(" ...\r\n"),false) == 0 )
            text.Replace(_T("\n"), _T(" ...\n"),false);
    }

    // add the actual text
    buffer << text;

    if ( CmtType == tdctStream )
        buffer << _T(" ") << token.streamCommentEnd;
    if ( CmtType == tdctDoxygenStream )
        buffer << _T(" ") << token.doxygenStreamCommentEnd;

    // add newline char(s), only if dlg.GetPosition() != tdpCurrent
    if (dlg.GetPosition() != tdpCurrent)
        buffer << GetEOLStr(control->GetEOLMode());

    // ok, insert the todo line text
    control->InsertText(idx, buffer);
    if (dlg.GetPosition() == tdpAbove)
        origPos += buffer.Length() + crlfLen;
    control->GotoPos(origPos);
    control->EnsureCaretVisible();

    ParseCurrent(true);
} // end of OnAddItem