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
|
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// 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 <vector>
#include <map>
#include <list>
#include <wx/stc/stc.h>
#include "wx/debug.h"
#include "notebook_ex.h"
#include "outputtabwindow.h"
#include "search_thread.h"
#include "findinfilesdlg.h"
// Map between the line numbers and a search results
typedef std::map<int, SearchResult> MatchInfo;
// List containing the match info for all tabs (pre location)
typedef std::list<MatchInfo> ListMatchInfos;
class FindResultsTab : public OutputTabWindow
{
SearchData m_searchData;
bool m_searchInProgress;
protected:
Notebook *m_book; // for multiple Find Results pages
wxStyledTextCtrl *m_recv; // the page that is receiving results of a search
ListMatchInfos m_matchInfo;
MatchInfo& GetMatchInfo(size_t idx = 0);
void AppendText(const wxString &line);
void Clear();
virtual void OnPageClosed (NotebookEvent &e);
virtual void OnPageChanged (NotebookEvent &e);
virtual void OnClosePage (NotebookEvent &e);
virtual void OnFindInFiles (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 OnCloseTab (wxCommandEvent &e);
virtual void OnCloseAllTabs (wxCommandEvent &e);
virtual void OnCloseOtherTab (wxCommandEvent &e);
virtual void OnTabMenuUI (wxUpdateUIEvent &e);
virtual void OnClearAllUI (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 (wxStyledTextCtrl *sci );
void DoOpenSearchResult(const SearchResult &result, wxStyledTextCtrl *sci, int markerLine);
void OnThemeChanged (wxCommandEvent &e);
DECLARE_EVENT_TABLE()
public:
FindResultsTab(wxWindow *parent, wxWindowID id, const wxString &name, bool useBook = false);
~FindResultsTab();
long GetBookStyle();
static void SetStyles(wxStyledTextCtrl *sci);
static void StyleText(wxStyledTextCtrl* ctrl, wxStyledTextEvent& e);
size_t GetPageCount() const ;
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__
|