Permalink
Browse files

Added a method for navigating selections.

By pressing Ctrl+Alt+Shift+N, the selections are converted to highlights, and the first selection is selected.
The user can type and do whatever.  Pressing Ctrl+Alt+Shift+U will take the user to the next selection.
This is quite helpful when editing similar code or data that has been copy and pasted.
  • Loading branch information...
1 parent 1c05ac9 commit 5228490efe7a78d8ff46abaeb8e54e0f4be56562 @ajpalkovic ajpalkovic committed Jun 26, 2010
Showing with 310 additions and 1 deletion.
  1. +18 −0 src/EditorCtrl.cpp
  2. +6 −0 src/EditorCtrl.h
  3. +28 −0 src/EditorFrame.cpp
  4. +8 −1 src/EditorFrame.h
  5. +8 −0 src/e.vcproj
  6. +172 −0 src/styler_selections.cpp
  7. +70 −0 src/styler_selections.h
View
@@ -165,6 +165,7 @@ EditorCtrl::EditorCtrl(const int page_id, CatalystWrapper& cw, wxBitmap& bitmap,
m_variable_hl_styler(m_doc, m_lines, m_searchRanges, m_theme, eGetSettings(), *this),
m_html_hl_styler(m_doc, m_lines, m_theme, eGetSettings(), *this),
m_syntaxstyler(m_doc, m_lines, &m_syntaxHandler),
+ m_selectionsStyler(m_doc, m_lines, m_theme, *this),
m_foldTooltipTimer(this, TIMER_FOLDTOOLTIP),
m_activeTooltip(NULL),
@@ -220,6 +221,7 @@ EditorCtrl::EditorCtrl(const doc_id di, const wxString& mirrorPath, CatalystWrap
m_variable_hl_styler(m_doc, m_lines, m_searchRanges, m_theme, eGetSettings(), *this),
m_html_hl_styler(m_doc, m_lines, m_theme, eGetSettings(), *this),
m_syntaxstyler(m_doc, m_lines, &m_syntaxHandler),
+ m_selectionsStyler(m_doc, m_lines, m_theme, *this),
m_foldTooltipTimer(this, TIMER_FOLDTOOLTIP),
m_activeTooltip(NULL),
@@ -290,6 +292,7 @@ EditorCtrl::EditorCtrl(CatalystWrapper& cw, wxBitmap& bitmap, wxWindow* parent,
m_variable_hl_styler(m_doc, m_lines, m_searchRanges, m_theme, eGetSettings(), *this),
m_html_hl_styler(m_doc, m_lines, m_theme, eGetSettings(), *this),
m_syntaxstyler(m_doc, m_lines, &m_syntaxHandler),
+ m_selectionsStyler(m_doc, m_lines, m_theme, *this),
m_foldTooltipTimer(this, TIMER_FOLDTOOLTIP),
m_activeTooltip(NULL),
@@ -456,6 +459,7 @@ void EditorCtrl::Init() {
m_lines.AddStyler(m_search_hl_styler);
m_lines.AddStyler(m_variable_hl_styler);
m_lines.AddStyler(m_html_hl_styler);
+ m_lines.AddStyler(m_selectionsStyler);
// Set initial tabsize
if(!m_tabSettingsFromSyntax) {
@@ -8976,3 +8980,17 @@ wxDragResult DragDropTarget::OnData(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wx
return def;
}
+
+void EditorCtrl::NavigateSelections() {
+ m_selectionsStyler.EnableNavigation();
+}
+
+void EditorCtrl::NextSelection() {
+ m_selectionsStyler.NextSelection();
+ DrawLayout();
+}
+
+void EditorCtrl::PreviousSelection() {
+ m_selectionsStyler.PreviousSelection();
+ DrawLayout();
+}
View
@@ -42,6 +42,7 @@
#include "IEditorSymbols.h"
#include "IEditorSearch.h"
#include "ITabPage.h"
+#include "styler_selections.h"
class wxFileName;
@@ -211,6 +212,10 @@ class EditorCtrl : public KeyHookable<wxControl>,
void SelectScope();
void SelectParentTag();
+ void NavigateSelections();
+ void NextSelection();
+ void PreviousSelection();
+
// Movement commands
void SetPos(unsigned int pos);
void SetPos(int line, int column);
@@ -536,6 +541,7 @@ class EditorCtrl : public KeyHookable<wxControl>,
Styler_VariableHL m_variable_hl_styler;
Styler_HtmlHL m_html_hl_styler;
Styler_Syntax m_syntaxstyler;
+ Styler_Selections m_selectionsStyler;
wxTimer m_foldTooltipTimer;
TextTip* m_activeTooltip;
View
@@ -284,6 +284,10 @@ BEGIN_EVENT_TABLE(EditorFrame, wxFrame)
EVT_FILESCHANGED(EditorFrame::OnFilesChanged)
EVT_MOUSEWHEEL(EditorFrame::OnMouseWheel)
+
+ EVT_MENU(MENU_NAVIGATE_SELECTIONS_MODE, EditorFrame::OnMenuNavigateSelections)
+ EVT_MENU(MENU_NAVIGATE_SELECTIONS_NEXT, EditorFrame::OnMenuNavigateSelectionsNext)
+ EVT_MENU(MENU_NAVIGATE_SELECTIONS_PREVIOUS, EditorFrame::OnMenuNavigateSelectionsPrevious)
//EVT_MENU(MENU_DOC_OPEN, EditorFrame::OnMenuDocOpen)
//EVT_MENU(MENU_DOC_SHARE, EditorFrame::OnMenuDocShare)
@@ -590,6 +594,12 @@ void EditorFrame::InitMenus() {
selectMenu->Append(MENU_SELECTTAG, _("Tag &Content\tCtrl+,"), _("Select Parent Tag Content"));
editMenu->Append(MENU_SELECT, _("&Select"), selectMenu, _("Select"));
+ wxMenu* navigateSelectionsMenu = new wxMenu;
+ navigateSelectionsMenu->Append(MENU_NAVIGATE_SELECTIONS_MODE, _("&Navigate Selections\tCtrl+Alt+Shift+N"), _("Navigate Selections"));
+ navigateSelectionsMenu->Append(MENU_NAVIGATE_SELECTIONS_NEXT, _("&Next Selection\tCtrl+Alt+Shift+U"), _("Next Selection"));
+ navigateSelectionsMenu->Append(MENU_NAVIGATE_SELECTIONS_PREVIOUS, _("&Previous Selection\tCtrl+Alt+Shift+I"), _("Previous Selection"));
+ editMenu->Append(MENU_NAVIGATE_SELECTIONS, _("&Navigate Selections"), navigateSelectionsMenu, _("Navigate Selections"));
+
editMenu->AppendSeparator();
wxMenu* findMenu = new wxMenu;
findMenu->Append(wxID_FIND, _("&Find\tCtrl+F"), _("Find"));
@@ -3990,3 +4000,21 @@ void EditorFrame::OnMouseWheel(wxMouseEvent& event) {
// If no one else handled the event, send it to the editor.
this->editorCtrl->ProcessMouseWheel(event);
}
+
+void EditorFrame::OnMenuNavigateSelections(wxCommandEvent& WXUNUSED(event)) {
+ EditorCtrl* ec = GetEditorCtrl();
+ if(!ec) return;
+ ec->NavigateSelections();
+}
+
+void EditorFrame::OnMenuNavigateSelectionsNext(wxCommandEvent& WXUNUSED(event)) {
+ EditorCtrl* ec = GetEditorCtrl();
+ if(!ec) return;
+ ec->NextSelection();
+}
+
+void EditorFrame::OnMenuNavigateSelectionsPrevious(wxCommandEvent& WXUNUSED(event)) {
+ EditorCtrl* ec = GetEditorCtrl();
+ if(!ec) return;
+ ec->PreviousSelection();
+}
View
@@ -179,7 +179,11 @@ class EditorFrame : public KeyHookable<wxFrame>,
MENU_BOOKMARK_CLEAR,
MENU_MARK_COPY,
MENU_FIND_REPLACE,
- MENU_FIND_REPLACE_ALL
+ MENU_FIND_REPLACE_ALL,
+ MENU_NAVIGATE_SELECTIONS,
+ MENU_NAVIGATE_SELECTIONS_MODE,
+ MENU_NAVIGATE_SELECTIONS_NEXT,
+ MENU_NAVIGATE_SELECTIONS_PREVIOUS
};
EditorFrame(CatalystWrapper cat, unsigned int frameId, const wxString& title, const wxRect& rect, TmSyntaxHandler& syntax_handler);
@@ -447,6 +451,9 @@ class EditorFrame : public KeyHookable<wxFrame>,
void OnMenuEditBundles(wxCommandEvent& event);
void OnMenuManageBundles(wxCommandEvent& event);
void OnMenuBundleAction(wxCommandEvent& event);
+ void OnMenuNavigateSelections(wxCommandEvent& event);
+ void OnMenuNavigateSelectionsNext(wxCommandEvent& event);
+ void OnMenuNavigateSelectionsPrevious(wxCommandEvent& event);
void OnMenuKeyDiagnostics(wxCommandEvent& event);
void OnTabsShowDropdown(wxCommandEvent& event);
View
@@ -1125,6 +1125,14 @@
>
</File>
<File
+ RelativePath=".\styler_selections.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\styler_selections.h"
+ >
+ </File>
+ <File
RelativePath="styler_syntax.cpp"
>
</File>
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ *
+ * Copyright (C) 2009, Alexander Stigsen, e-texteditor.com
+ *
+ * This software is licensed under the Open Company License as described
+ * in the file license.txt, which you should have received as part of this
+ * distribution. The terms are also available at http://opencompany.org/license.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ******************************************************************************/
+
+#include "styler_selections.h"
+
+#include "StyleRun.h"
+#include "Lines.h"
+#include "Document.h"
+#include "EditorCtrl.h"
+
+Styler_Selections::Styler_Selections(const DocumentWrapper& rev, const Lines& lines, const tmTheme& theme, EditorCtrl& editorCtrl)
+: m_doc(rev), m_lines(lines), m_editorCtrl(editorCtrl),
+ m_theme(theme), m_searchHighlightColor(m_theme.searchHighlightColor),
+ m_selectionHighlightColor(m_theme.selectionColor),
+ m_enabled(false)
+{
+}
+
+void Styler_Selections::Invalidate() {
+ m_selections.clear();
+ m_nextSelection = -1;
+ m_enabled = false;
+}
+
+void Styler_Selections::EnableNavigation() {
+ m_enabled = !m_enabled;
+
+ if(m_enabled) {
+ m_nextSelection = -1;
+ m_selections = m_editorCtrl.GetSelections();
+ NextSelection();
+ }
+}
+
+void Styler_Selections::NextSelection() {
+ if(!m_enabled) return;
+
+ m_nextSelection++;
+ if(m_nextSelection >= m_selections.size()) {
+ m_nextSelection = 0;
+ }
+
+ m_editorCtrl.RemoveAllSelections();
+ m_editorCtrl.SetPos(m_selections[m_nextSelection].start);
+ m_editorCtrl.Select(m_selections[m_nextSelection].start, m_selections[m_nextSelection].end);
+ m_editorCtrl.DrawLayout();
+}
+
+void Styler_Selections::PreviousSelection() {
+ if(!m_enabled) return;
+
+ m_nextSelection--;
+ if(m_nextSelection < 0) {
+ m_nextSelection = m_selections.size()-1;
+ }
+
+ m_editorCtrl.RemoveAllSelections();
+ m_editorCtrl.SetPos(m_selections[m_nextSelection].start);
+ m_editorCtrl.Select(m_selections[m_nextSelection].start, m_selections[m_nextSelection].end);
+ m_editorCtrl.DrawLayout();
+}
+
+void Styler_Selections::Style(StyleRun& sr) {
+ if(!m_enabled) return;
+
+ const unsigned int rstart = sr.GetRunStart();
+ const unsigned int rend = sr.GetRunEnd();
+
+ for(unsigned int c = 0; c < m_selections.size(); c++) {
+ unsigned int start = m_selections[c].start;
+ unsigned int end = m_selections[c].end;
+
+ if (start > rend) break;
+
+ // Check for overlap (or zero-length sel at start-of-line)
+ if ((end > rstart && start < rend) || (start == end && end == rstart)) {
+ start = wxMax(rstart, start);
+ end = wxMin(rend, end);
+
+ ApplyStyle(sr, start, end);
+ }
+ }
+}
+
+void Styler_Selections::ApplyStyle(StyleRun& sr, unsigned int start, unsigned int end) {
+ unsigned int pos = m_editorCtrl.GetPos();
+ if(start <= pos && end >= pos) {
+ sr.SetBackgroundColor(start, end, m_selectionHighlightColor);
+ } else {
+ sr.SetBackgroundColor(start, end, m_searchHighlightColor);
+ }
+ sr.SetShowHidden(start, end, true);
+}
+
+void Styler_Selections::Insert(unsigned int pos, unsigned int length) {
+ wxASSERT(0 <= pos && pos < m_doc.GetLength());
+ wxASSERT(0 <= length && pos+length <= m_doc.GetLength());
+
+ if(!m_enabled) return;
+
+ for(unsigned int c = 0; c < m_selections.size(); c++) {
+ unsigned int start = m_selections[c].start;
+ unsigned int end = m_selections[c].end;
+
+ if(start > pos) {
+ m_selections[c].start += length;
+ m_selections[c].end += length;
+ } else if(end >= pos) {
+ m_selections[c].end += length;
+ }
+ }
+}
+
+void Styler_Selections::Delete(unsigned int start_pos, unsigned int end_pos) {
+ wxASSERT(0 <= start_pos && start_pos <= m_doc.GetLength());
+ if(!m_enabled) return;
+
+ if (start_pos == end_pos) return;
+ wxASSERT(end_pos > start_pos);
+
+ // Check if we have deleted the entire document
+ if (m_doc.GetLength() == 0) {
+ Invalidate();
+ return;
+ }
+
+ unsigned int length = end_pos - start_pos;
+ unsigned int size = m_selections.size();
+
+ for(unsigned int c = 0; c < size; c++) {
+ unsigned int start = m_selections[c].start;
+ unsigned int end = m_selections[c].end;
+
+ if(start_pos > end) {
+ //deleted text is all after, so ignore
+ } else if(end_pos < start) {
+ //deleted text is all before, so shift
+ m_selections[c].start -= length;
+ m_selections[c].end -= length;
+ } else if(start_pos == start && end_pos == end) {
+ //deleted all text in the selection, but don't get rid of the selection
+ m_selections[c].end = start;
+ } else if(start_pos >= start && end_pos <= end) {
+ //deleted text in all inside the selection, so shift end
+ m_selections[c].end -= length;
+ } else {
+ //deleted text in some way encompasses teh whole selection, so ditch it
+ if(c <= m_nextSelection) {
+ m_nextSelection--;
+ }
+ m_selections.erase(m_selections.begin()+c);
+ c--;
+ size--;
+ }
+ }
+
+ m_enabled = m_selections.size() > 0;
+}
+
+void Styler_Selections::ApplyDiff(std::vector<cxChange>& WXUNUSED(changes)) {
+ Invalidate();
+}
Oops, something went wrong.

0 comments on commit 5228490

Please sign in to comment.