1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright : (C) 2008 by Eran Ifrah
// file name : findresultstab.h
//
// -------------------------------------------------------------------------
// A
// _____ _ _ _ _
// / __ \ | | | | (_) |
// | / \/ ___ __| | ___| | _| |_ ___
// | | / _ \ / _ |/ _ \ | | | __/ _ )
// | \__/\ (_) | (_| | __/ |___| | || __/
// \____/\___/ \__,_|\___\_____/_|\__\___|
//
// F i l e
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#ifndef __findresultstab__
#define __findresultstab__
#include "Notebook.h"
#include "clWorkspaceEvent.hpp"
#include "findinfilesdlg.h"
#include "outputtabwindow.h"
#include "search_thread.h"
#include "wx/debug.h"
#include "wx_ordered_map.h"
#include <map>
#include <unordered_map>
#include <vector>
#include <wx/aui/auibar.h>
#include <wx/stc/stc.h>
// Map between the line numbers and a search results
typedef std::map<int, SearchResult> MatchInfo_t;
class FindResultsTab : public OutputTabWindow
{
protected:
SearchData m_searchData;
wxString m_searchTitle;
std::vector<int> m_indicators;
bool m_searchInProgress;
bool m_searchEventsConnected = false;
struct History {
wxString title;
SearchData searchData;
wxString text;
MatchInfo_t matchInfo;
std::vector<int> indicators;
typedef wxOrderedMap<wxString, History> Map_t;
};
History::Map_t m_history;
protected:
MatchInfo_t m_matchInfo;
void UnbindSearchEvents(wxEvtHandler* binder);
void BindSearchEvents(wxEvtHandler* binder);
void AppendLine(const wxString& line, bool scroll_to_bottom = true);
void Clear();
void SaveSearchData();
void LoadSearch(const History& h);
virtual void OnFindInFiles(wxCommandEvent& e);
virtual void OnRecentSearches(wxCommandEvent& e);
virtual void OnSearchStart(wxCommandEvent& e);
virtual void OnSearchMatch(wxCommandEvent& e);
virtual void OnSearchEnded(wxCommandEvent& e);
virtual void OnSearchCancel(wxCommandEvent& e);
virtual void OnClearAll(wxCommandEvent& e);
virtual void OnRepeatOutput(wxCommandEvent& e);
virtual void OnClearAllUI(wxUpdateUIEvent& e);
virtual void OnRecentSearchesUI(wxUpdateUIEvent& e);
virtual void OnRepeatOutputUI(wxUpdateUIEvent& e);
virtual void OnMouseDClick(wxStyledTextEvent& e);
virtual void OnStopSearch(wxCommandEvent& e);
virtual void OnStopSearchUI(wxUpdateUIEvent& e);
virtual void OnHoldOpenUpdateUI(wxUpdateUIEvent& e);
virtual void OnStyleNeeded(wxStyledTextEvent& e);
SearchData* GetSearchData();
void DoOpenSearchResult(const SearchResult& result, wxStyledTextCtrl* sci, int markerLine);
void OnThemeChanged(wxCommandEvent& e);
void OnWorkspaceClosed(clWorkspaceEvent& event);
DECLARE_EVENT_TABLE()
public:
FindResultsTab(wxWindow* parent, wxWindowID id, const wxString& name);
~FindResultsTab();
virtual void SetStyles(wxStyledTextCtrl* sci);
void StyleText(wxStyledTextCtrl* ctrl, wxStyledTextEvent& e, bool hasSope = false);
void ResetStyler();
void NextMatch();
void PrevMatch();
};
class EditorDeltasHolder
{
// This is all conceptually complex, so I'm being verbose for my own benefit
// m_changes contains the current state: any position deltas since the file was loaded/reverted
// m_changesAtLastSave is a snapshot of m_changes when the file was (last) saved
// m_changesForCurrentMatches is a snapshot of m_changes at the last FileInFiles, so is the baseline for current
// matches
// (Any or all may be empty)
// If the file is saved, that makes no difference to any existing FiF matches, so the above situation continues.
// However we cache m_changes in m_changesAtLastSave
// If another FindInFiles call is made, we no longer care about the m_changesForCurrentMatches contents as the
// corresponding matches will have been overwritten.
// So we replace m_changesForCurrentMatches with m_changesAtLastSave, which is the baseline for the new matches
// Note that, unless the file is saved at some point after an initial FiF call, both will be empty
// And, unless there's been a 'save' since the last FiF call, the contents of m_changesForCurrentMatches and
// m_changesAtLastSave will be the same
// When there's a 'GoTo next/previous FindInFiles' call, any relevant position changes need to be used. There are 4
// possibilities:
// 1) If there are no changes, FiF matches should 'just work'
// 2) The common non-trivial situation is for there to be +ve position changes subsequent to the
// file's
// saved
// status at the last FindInFiles call
// However, see below...
// 3) Occasionally there will have been -ve position changes (i.e. undos), or undos followed by
// different
// alterations.
// If there hasn't been a second FiF call, that won't matter.
// 4) If there *has* been a second FiF call, followed by more alterations, it *will* matter; especially if
// there
// have been undos, then different alterations.
// In that case we need to use both the original changes and the replacement ones.
// As there's no easy way to tell the difference between 2) 3) and 4) (and the cost is nil for 1) anyway) treat all
// cases as though they may be 4) instances.
// That means combining m_changesForCurrentMatches (reversed and with lengths negated) and m_changes. See
// GetChanges()
public:
EditorDeltasHolder() {}
~EditorDeltasHolder() { Clear(); }
void Clear()
{
m_changes.clear();
m_changesAtLastSave.clear();
m_changesForCurrentMatches.clear();
}
void Push(int position, int length)
{
m_changes.push_back(position);
m_changes.push_back(length);
}
void Pop()
{
if(m_changes.size() > 1) {
m_changes.pop_back();
m_changes.pop_back();
}
}
void OnFileSaved() { m_changesAtLastSave = m_changes; }
void OnFileInFiles() { m_changesForCurrentMatches = m_changesAtLastSave; }
void GetChanges(std::vector<int>& changes);
protected:
std::vector<int> m_changes;
std::vector<int> m_changesAtLastSave;
std::vector<int> m_changesForCurrentMatches;
};
#endif // __findresultstab__
|