Feature #25 Fast commenting
This commit is contained in:
parent
fe0102dddd
commit
fe2cd0713b
|
@ -1,4 +1,5 @@
|
||||||
1.2.1.1
|
1.2.1.1
|
||||||
|
+ Feature #25 Fast commenting
|
||||||
+ x64 installation package
|
+ x64 installation package
|
||||||
* Fixed tab order
|
* Fixed tab order
|
||||||
* Fixed encoding problems
|
* Fixed encoding problems
|
||||||
|
|
|
@ -131,6 +131,7 @@ BEGIN_EVENT_TABLE ( MyFrame, wxFrame )
|
||||||
EVT_MENU ( ID_FIND, MyFrame::OnFind )
|
EVT_MENU ( ID_FIND, MyFrame::OnFind )
|
||||||
EVT_MENU ( ID_FIND_AGAIN, MyFrame::OnFindAgain )
|
EVT_MENU ( ID_FIND_AGAIN, MyFrame::OnFindAgain )
|
||||||
EVT_MENU ( ID_GOTO, MyFrame::OnGoto )
|
EVT_MENU ( ID_GOTO, MyFrame::OnGoto )
|
||||||
|
EVT_MENU ( ID_TOGGLE_COMMENT, MyFrame::OnToggleComment )
|
||||||
EVT_MENU ( ID_FEEDBACK, MyFrame::OnFeedback )
|
EVT_MENU ( ID_FEEDBACK, MyFrame::OnFeedback )
|
||||||
EVT_MENU ( ID_PREVIOUS_DOCUMENT, MyFrame::OnPreviousDocument )
|
EVT_MENU ( ID_PREVIOUS_DOCUMENT, MyFrame::OnPreviousDocument )
|
||||||
EVT_MENU ( ID_NEXT_DOCUMENT, MyFrame::OnNextDocument )
|
EVT_MENU ( ID_NEXT_DOCUMENT, MyFrame::OnNextDocument )
|
||||||
|
@ -2799,6 +2800,16 @@ void MyFrame::OnGlobalReplace ( wxCommandEvent& event )
|
||||||
statusProgress ( msg );
|
statusProgress ( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnToggleComment ( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
XmlDoc *doc = getActiveDocument();
|
||||||
|
if ( doc == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxBusyCursor cursor;
|
||||||
|
doc->toggleComment();
|
||||||
|
}
|
||||||
|
|
||||||
void MyFrame::OnFrameClose ( wxCloseEvent& event )
|
void MyFrame::OnFrameClose ( wxCloseEvent& event )
|
||||||
{
|
{
|
||||||
wxCommandEvent e;
|
wxCommandEvent e;
|
||||||
|
@ -4936,6 +4947,10 @@ wxMenuBar *MyFrame::getMenuBar()
|
||||||
new wxMenuItem ( NULL, ID_GOTO, _ ( "G&o To...\tCtrl+G" ), _ ( "Go To..." ) );
|
new wxMenuItem ( NULL, ID_GOTO, _ ( "G&o To...\tCtrl+G" ), _ ( "Go To..." ) );
|
||||||
gotoItem->SetBitmap ( wxNullBitmap );
|
gotoItem->SetBitmap ( wxNullBitmap );
|
||||||
|
|
||||||
|
wxMenuItem *commentItem =
|
||||||
|
new wxMenuItem ( NULL, ID_TOGGLE_COMMENT, _ ( "&Toggle Comment\tCtrl+/" ), _ ( "Toggle Comment" ) );
|
||||||
|
commentItem->SetBitmap ( wxNullBitmap );
|
||||||
|
|
||||||
editMenu->Append ( undoItem );
|
editMenu->Append ( undoItem );
|
||||||
editMenu->Append ( redoItem );
|
editMenu->Append ( redoItem );
|
||||||
editMenu->AppendSeparator();
|
editMenu->AppendSeparator();
|
||||||
|
@ -4948,8 +4963,9 @@ wxMenuBar *MyFrame::getMenuBar()
|
||||||
editMenu->Append ( findAgainItem );
|
editMenu->Append ( findAgainItem );
|
||||||
editMenu->Append ( replaceItem );
|
editMenu->Append ( replaceItem );
|
||||||
editMenu->Append ( globalReplaceItem );
|
editMenu->Append ( globalReplaceItem );
|
||||||
editMenu->AppendSeparator();
|
|
||||||
editMenu->Append ( gotoItem );
|
editMenu->Append ( gotoItem );
|
||||||
|
editMenu->AppendSeparator();
|
||||||
|
editMenu->Append ( commentItem );
|
||||||
|
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
wxMenuItem *preferencesItem =
|
wxMenuItem *preferencesItem =
|
||||||
|
|
|
@ -109,6 +109,7 @@ enum
|
||||||
ID_FIND,
|
ID_FIND,
|
||||||
ID_FIND_AGAIN,
|
ID_FIND_AGAIN,
|
||||||
ID_GOTO,
|
ID_GOTO,
|
||||||
|
ID_TOGGLE_COMMENT,
|
||||||
ID_PRINT,
|
ID_PRINT,
|
||||||
ID_WORD_COUNT,
|
ID_WORD_COUNT,
|
||||||
ID_PRINT_PREVIEW,
|
ID_PRINT_PREVIEW,
|
||||||
|
@ -235,6 +236,7 @@ class MyFrame : public wxFrame
|
||||||
void OnFindReplace ( wxCommandEvent& event );
|
void OnFindReplace ( wxCommandEvent& event );
|
||||||
void OnCommand ( wxCommandEvent& event );
|
void OnCommand ( wxCommandEvent& event );
|
||||||
void OnGlobalReplace ( wxCommandEvent& event );
|
void OnGlobalReplace ( wxCommandEvent& event );
|
||||||
|
void OnToggleComment ( wxCommandEvent& event );
|
||||||
void OnWordCount ( wxCommandEvent& event );
|
void OnWordCount ( wxCommandEvent& event );
|
||||||
void OnFeedback ( wxCommandEvent& event );
|
void OnFeedback ( wxCommandEvent& event );
|
||||||
void OnSplitTab ( wxCommandEvent& event );
|
void OnSplitTab ( wxCommandEvent& event );
|
||||||
|
|
218
src/xmlctrl.cpp
218
src/xmlctrl.cpp
|
@ -973,40 +973,102 @@ wxString XmlCtrl::getLastAttributeName ( int pos )
|
||||||
return GetTextRange ( startPos + 1, pos );
|
return GetTextRange ( startPos + 1, pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
int XmlCtrl::getParentCloseAngleBracket ( int pos, int range )
|
int XmlCtrl::findNextEndTag (
|
||||||
|
int pos,
|
||||||
|
unsigned depth /*= 1*/,
|
||||||
|
int character /*= '>'*/,
|
||||||
|
int range /*= USHRT_MAX * 4*/ )
|
||||||
{
|
{
|
||||||
int cutoff, iteratorPos, depth;
|
wxASSERT ( character == '<' || character == '>' );
|
||||||
cutoff = ( ( pos - range ) > 2 ) ? pos - range : 2;
|
|
||||||
depth = 1;
|
|
||||||
for (
|
|
||||||
iteratorPos = pos;
|
|
||||||
iteratorPos > cutoff;
|
|
||||||
--iteratorPos )
|
|
||||||
{
|
|
||||||
int type, style;
|
|
||||||
style = getLexerStyleAt ( iteratorPos );
|
|
||||||
|
|
||||||
if ( GetCharAt ( iteratorPos ) == '>' &&
|
unsigned openAngleBrackets = 0;
|
||||||
( style == wxSTC_H_TAG ||
|
int cutoff = pos + range;
|
||||||
style == wxSTC_H_TAGUNKNOWN ) )
|
if ( cutoff > GetEndStyled() )
|
||||||
|
cutoff = GetEndStyled();
|
||||||
|
for ( ; pos < cutoff; ++pos )
|
||||||
{
|
{
|
||||||
type = getTagType ( iteratorPos );
|
int ch = GetCharAt ( pos );
|
||||||
|
if ( ch == '<' )
|
||||||
|
openAngleBrackets = ( openAngleBrackets << 1 ) | 1;// Just a flag
|
||||||
|
// Check for empty tags, which have start tags but no end tags
|
||||||
|
if ( character != '>' || !openAngleBrackets )
|
||||||
|
if ( ch == '>' && getLexerStyleAt ( pos ) == wxSTC_H_TAGEND )
|
||||||
|
--depth;
|
||||||
|
if ( ch != character )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int style = getLexerStyleAt ( pos );
|
||||||
|
if ( style == wxSTC_H_TAG || style == wxSTC_H_TAGUNKNOWN )
|
||||||
|
{
|
||||||
|
int type = getTagType ( pos );
|
||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
case ( TAG_TYPE_CLOSE ) :
|
case TAG_TYPE_CLOSE:
|
||||||
++depth;
|
|
||||||
break;
|
|
||||||
case ( TAG_TYPE_OPEN ) :
|
|
||||||
--depth;
|
--depth;
|
||||||
break;
|
break;
|
||||||
case ( TAG_TYPE_EMPTY ) :
|
case TAG_TYPE_OPEN:
|
||||||
case ( TAG_TYPE_OTHER ) :
|
// In case that the cursor is inside a start tag
|
||||||
case ( TAG_TYPE_ERROR ) :
|
if ( character != '>' || openAngleBrackets > 0 )
|
||||||
|
++depth;
|
||||||
|
break;
|
||||||
|
case TAG_TYPE_EMPTY:
|
||||||
|
case TAG_TYPE_OTHER:
|
||||||
|
case TAG_TYPE_ERROR:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( !depth )
|
|
||||||
return iteratorPos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !depth )
|
||||||
|
return pos + 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int XmlCtrl::findPreviousStartTag (
|
||||||
|
int pos,
|
||||||
|
unsigned depth /*= 1*/,
|
||||||
|
int character /*= '<'*/,
|
||||||
|
int range /*= USHRT_MAX * 4*/ )
|
||||||
|
{
|
||||||
|
wxASSERT ( character == '<' || character == '>' );
|
||||||
|
|
||||||
|
int cutoff = ( ( pos - range ) > 2 ) ? pos - range : 2;
|
||||||
|
unsigned closeAngleBrackets = 0;
|
||||||
|
while ( pos-- > cutoff )
|
||||||
|
{
|
||||||
|
int ch = GetCharAt ( pos );
|
||||||
|
if ( ch == '>' )
|
||||||
|
{
|
||||||
|
closeAngleBrackets = ( closeAngleBrackets << 1 ) | 1;// Just a flag
|
||||||
|
// Check for empty tags, which have start tags but no end tags
|
||||||
|
if ( character != '>' && getLexerStyleAt ( pos ) == wxSTC_H_TAGEND )
|
||||||
|
++depth;
|
||||||
|
}
|
||||||
|
if ( ch != character )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int style = getLexerStyleAt ( pos );
|
||||||
|
if ( style == wxSTC_H_TAG || style == wxSTC_H_TAGUNKNOWN )
|
||||||
|
{
|
||||||
|
int type = getTagType ( pos );
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case TAG_TYPE_CLOSE:
|
||||||
|
// If the cursor is already in an end tag
|
||||||
|
if ( character != '<' || closeAngleBrackets > 0 )
|
||||||
|
++depth;
|
||||||
|
break;
|
||||||
|
case TAG_TYPE_OPEN:
|
||||||
|
--depth;
|
||||||
|
break;
|
||||||
|
case TAG_TYPE_EMPTY:
|
||||||
|
case TAG_TYPE_OTHER:
|
||||||
|
case TAG_TYPE_ERROR:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !depth )
|
||||||
|
return pos;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2119,3 +2181,111 @@ void XmlCtrl::OnMiddleDown ( wxMouseEvent& event )
|
||||||
SetSelection ( pastePosition, pastePosition );
|
SetSelection ( pastePosition, pastePosition );
|
||||||
Paste();
|
Paste();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XmlCtrl::toggleComment()
|
||||||
|
{
|
||||||
|
int pos = -1;
|
||||||
|
wxString text = GetSelectedText();
|
||||||
|
if ( text.IsEmpty() )
|
||||||
|
{
|
||||||
|
if ( type == FILE_TYPE_BINARY )
|
||||||
|
return;
|
||||||
|
|
||||||
|
pos = GetCurrentPos();
|
||||||
|
Colourise ( 0, -1 );
|
||||||
|
|
||||||
|
int style = getLexerStyleAt ( pos ) ;
|
||||||
|
if ( style == wxSTC_H_COMMENT )
|
||||||
|
{
|
||||||
|
int i = pos;
|
||||||
|
while ( --i >= 0 && getLexerStyleAt ( i ) == wxSTC_H_COMMENT )
|
||||||
|
continue;
|
||||||
|
SetSelectionStart ( i + 1 );
|
||||||
|
|
||||||
|
int styled = GetEndStyled();
|
||||||
|
i = pos;
|
||||||
|
while ( i < styled && getLexerStyleAt ( i ) == wxSTC_H_COMMENT )
|
||||||
|
i++;
|
||||||
|
SetSelectionEnd ( i );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Select current tag
|
||||||
|
int start = findPreviousStartTag ( pos, 1, '<', pos );
|
||||||
|
if ( start < 0 )
|
||||||
|
{
|
||||||
|
wxMessageBox(_T("Cann't find the start tag"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int range = GetTextLength() - pos;
|
||||||
|
int end = findNextEndTag ( pos, 1, '>', range );
|
||||||
|
if ( end < 0 )
|
||||||
|
{
|
||||||
|
wxMessageBox(_T("Cann't find the end tag"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetSelection ( start, end );
|
||||||
|
}
|
||||||
|
text = GetSelectedText();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip leading spaces
|
||||||
|
wxString::iterator itr, start, end;
|
||||||
|
itr = start = text.begin();
|
||||||
|
end = text.end();
|
||||||
|
while ( itr != end && wxIsspace ( *itr ) )
|
||||||
|
++itr;
|
||||||
|
|
||||||
|
const static wxString commentStart = _T ( "<!--" );
|
||||||
|
const static wxString commentEnd = _T ( "-->" );
|
||||||
|
|
||||||
|
size_t offset = itr - start;
|
||||||
|
int ret = text.compare ( offset, commentStart.length(), commentStart );
|
||||||
|
if ( ret == 0 )
|
||||||
|
{
|
||||||
|
start = itr;
|
||||||
|
itr = end;
|
||||||
|
do {
|
||||||
|
--itr;
|
||||||
|
} while ( itr != start && wxIsspace ( *itr ) );
|
||||||
|
|
||||||
|
offset = itr - start;
|
||||||
|
if ( offset > commentEnd.length() )
|
||||||
|
{
|
||||||
|
offset = itr - text.begin() - commentEnd.length() + 1;
|
||||||
|
ret = text.compare ( offset, commentEnd.length(), commentEnd );
|
||||||
|
|
||||||
|
// Is commented?
|
||||||
|
if ( ret == 0 )
|
||||||
|
{
|
||||||
|
text.erase ( offset, commentEnd.length() );
|
||||||
|
text.erase ( start, start + commentStart.length() );
|
||||||
|
|
||||||
|
ReplaceSelection ( text );
|
||||||
|
if ( pos >= 0 )
|
||||||
|
{
|
||||||
|
pos -= commentStart.length();
|
||||||
|
SetEmptySelection ( pos >= 0 ? pos : 0 );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment selection
|
||||||
|
|
||||||
|
// "--" is not allowed in comments
|
||||||
|
const static wxString doubleHyphen = _T ( "--" );
|
||||||
|
offset = 0;
|
||||||
|
while ( ( offset = text.find ( doubleHyphen, offset ) ) != wxString::npos )
|
||||||
|
{
|
||||||
|
text.replace ( offset, doubleHyphen.length(), _T ( "- -" ) );
|
||||||
|
offset += 2; // WARNING: Not three!
|
||||||
|
}
|
||||||
|
|
||||||
|
text = commentStart + text + commentEnd;
|
||||||
|
|
||||||
|
ReplaceSelection ( text );
|
||||||
|
if ( pos >= 0 )
|
||||||
|
SetEmptySelection ( pos + commentStart.length() );
|
||||||
|
}
|
||||||
|
|
|
@ -109,7 +109,20 @@ class XmlCtrl: public wxStyledTextCtrl
|
||||||
long style = 0 );
|
long style = 0 );
|
||||||
~XmlCtrl();
|
~XmlCtrl();
|
||||||
int getType();
|
int getType();
|
||||||
int getParentCloseAngleBracket ( int pos, int range = USHRT_MAX * 4 );
|
int getParentCloseAngleBracket ( int pos )
|
||||||
|
{
|
||||||
|
return findPreviousStartTag ( pos, 1, '>' );
|
||||||
|
}
|
||||||
|
int findNextEndTag (
|
||||||
|
int pos,
|
||||||
|
unsigned depth = 1,
|
||||||
|
int character = '>',
|
||||||
|
int range = USHRT_MAX * 4 );
|
||||||
|
int findPreviousStartTag (
|
||||||
|
int pos,
|
||||||
|
unsigned depth = 1,
|
||||||
|
int character = '<',
|
||||||
|
int range = USHRT_MAX * 4 );
|
||||||
void applyProperties (
|
void applyProperties (
|
||||||
const XmlCtrlProperties &propertiesParameter,
|
const XmlCtrlProperties &propertiesParameter,
|
||||||
bool zoomOnly = false );
|
bool zoomOnly = false );
|
||||||
|
@ -144,6 +157,7 @@ class XmlCtrl: public wxStyledTextCtrl
|
||||||
std::string myGetTextRaw(); // alternative to faulty stc implementation
|
std::string myGetTextRaw(); // alternative to faulty stc implementation
|
||||||
bool getValidationRequired();
|
bool getValidationRequired();
|
||||||
void setValidationRequired ( bool b );
|
void setValidationRequired ( bool b );
|
||||||
|
void toggleComment();
|
||||||
private:
|
private:
|
||||||
ValidationThread *validationThread; // used for background validation
|
ValidationThread *validationThread; // used for background validation
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue