20
#include "configmanager.h"
21
#include "projectbuildtarget.h"
22
#include <wx/wxFlatNotebook/wxFlatNotebook.h>
24
#include "cbauibook.h"
24
26
#include "ThreadSearchThread.h"
25
27
#include "ThreadSearchEvent.h"
26
28
#include "TextFileSearcher.h"
28
30
ThreadSearchThread::ThreadSearchThread(ThreadSearchView* pThreadSearchView,
29
const ThreadSearchFindData& findData)
31
const ThreadSearchFindData& findData)
31
m_pThreadSearchView = pThreadSearchView;
32
m_FindData = findData;
34
// If wxDIR_IGNORE is used, we don't recurse in sub directories during directory search
35
m_DefaultDirResult = (findData.GetRecursiveSearch() == true) ? wxDIR_CONTINUE : wxDIR_IGNORE;
37
// File patterns separator is ';'
38
m_Masks = GetArrayFromString(m_FindData.GetSearchMask());
39
if ( m_Masks.GetCount() == 0 )
43
m_pTextFileSearcher = TextFileSearcher::BuildTextFileSearcher(findData.GetFindText(),
44
findData.GetMatchCase(),
45
findData.GetStartWord(),
46
findData.GetMatchWord(),
48
if (!m_pTextFileSearcher)
50
ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
51
event.SetString(_T("TextFileSearcher could not be instantiated."));
53
// Using wxPostEvent, we avoid multi-threaded memory violation.
54
wxPostEvent( m_pThreadSearchView,event);
33
m_pThreadSearchView = pThreadSearchView;
34
m_FindData = findData;
36
// If wxDIR_IGNORE is used, we don't recurse in sub directories during directory search
37
m_DefaultDirResult = (findData.GetRecursiveSearch() == true) ? wxDIR_CONTINUE : wxDIR_IGNORE;
39
// File patterns separator is ';'
40
m_Masks = GetArrayFromString(m_FindData.GetSearchMask());
41
if ( m_Masks.GetCount() == 0 )
45
m_pTextFileSearcher = TextFileSearcher::BuildTextFileSearcher(findData.GetFindText(),
46
findData.GetMatchCase(),
47
findData.GetStartWord(),
48
findData.GetMatchWord(),
50
if (!m_pTextFileSearcher)
52
ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
53
event.SetString(_("TextFileSearcher could not be instantiated."));
55
// Using wxPostEvent, we avoid multi-threaded memory violation.
56
wxPostEvent( m_pThreadSearchView,event);
58
ConfigManager* pCfg = Manager::Get()->GetConfigManager(_T("ThreadSearch"));
59
m_ShowFileMissingError=pCfg->ReadBool(wxT("/ShowFileMissingError"),true);
60
m_ShowCantOpenFileError=pCfg->ReadBool(wxT("/ShowCantOpenFileError"),true);
59
65
ThreadSearchThread::~ThreadSearchThread()
62
if ( m_pTextFileSearcher != NULL )
64
delete m_pTextFileSearcher;
68
if ( m_pTextFileSearcher != NULL )
70
delete m_pTextFileSearcher;
69
75
void *ThreadSearchThread::Entry()
71
// Tests if we have a working searcher object.
72
// Cancel search if it is not the case
73
if ( m_pTextFileSearcher == NULL )
78
// For now, we look for all paths for the different search scopes
79
// and store them in a sorted array to avoid pasing several times
81
// This will be changed to avoid consuming a lot of memory (parsing
82
// form C:\ and storing all paths...). Aim is to avoid the use of the
83
// array for storing items.
85
// Search in directory files ?
86
if ( m_FindData.MustSearchInDirectory() == true )
88
int flags = wxDIR_FILES | wxDIR_DIRS | wxDIR_DOTDOT;
89
flags |= m_FindData.GetHiddenSearch() ? wxDIR_HIDDEN : 0;
91
wxDir Dir(m_FindData.GetSearchPath());
92
Dir.Traverse(*(static_cast<wxDirTraverser*>(this)), wxEmptyString, flags);
94
// Tests thread stop (cancel search, app shutdown)
95
if ( TestDestroy() == true ) return 0;
98
// Search in workspace files ?
99
if ( m_FindData.MustSearchInWorkspace() == true )
101
ProjectsArray* pProjectsArray = Manager::Get()->GetProjectManager()->GetProjects();
102
for ( size_t i=0; i < pProjectsArray->GetCount(); ++i )
104
AddProjectFiles(m_FilePaths, *pProjectsArray->Item(i));
105
if ( TestDestroy() == true ) return 0;
108
else if ( m_FindData.MustSearchInProject() == true )
110
// Search in project files ?
111
// Necessary only if not already parsed in worspace part
112
cbProject* pProject = Manager::Get()->GetProjectManager()->GetActiveProject();
113
if ( pProject != NULL )
115
AddProjectFiles(m_FilePaths, *pProject);
116
if ( TestDestroy() == true ) return 0;
120
// Tests thread stop (cancel search, app shutdown)
121
if ( TestDestroy() == true ) return 0;
124
if ( m_FindData.MustSearchInOpenFiles() == true )
126
EditorManager* pEdManager = Manager::Get()->GetEditorManager();
127
for (i = 0; i < (size_t)pEdManager->GetNotebook()->GetPageCount(); ++i)
129
cbEditor* pEditor = pEdManager->GetBuiltinEditor(i);
130
if ( pEditor != NULL )
132
AddNewItem(m_FilePaths, pEditor->GetFilename());
137
// Tests thread stop (cancel search, app shutdown)
138
if ( TestDestroy() == true ) return 0;
140
// if the list is empty, leave
141
if (m_FilePaths.GetCount() == 0)
143
cbMessageBox(wxT("No files to search in!"), wxT("Error"), wxICON_WARNING);
147
for ( i = 0; i < m_FilePaths.GetCount(); ++i )
149
FindInFile(m_FilePaths[i]);
151
// Tests thread stop (cancel search, app shutdown)
152
if ( TestDestroy() == true ) return 0;
77
// Tests if we have a working searcher object.
78
// Cancel search if it is not the case
79
if ( m_pTextFileSearcher == NULL )
84
// For now, we look for all paths for the different search scopes
85
// and store them in a sorted array to avoid pasing several times
87
// This will be changed to avoid consuming a lot of memory (parsing
88
// form C:\ and storing all paths...). Aim is to avoid the use of the
89
// array for storing items.
91
// Search in directory files ?
92
if ( m_FindData.MustSearchInDirectory() == true )
94
int flags = wxDIR_FILES | wxDIR_DIRS | wxDIR_DOTDOT;
95
flags |= m_FindData.GetHiddenSearch() ? wxDIR_HIDDEN : 0;
97
wxDir Dir(m_FindData.GetSearchPath(true));
98
Dir.Traverse(*(static_cast<wxDirTraverser*>(this)), wxEmptyString, flags);
100
// Tests thread stop (cancel search, app shutdown)
101
if ( TestDestroy() == true ) return 0;
104
// Search in workspace files ?
105
if ( m_FindData.MustSearchInWorkspace() == true )
107
ProjectsArray* pProjectsArray = Manager::Get()->GetProjectManager()->GetProjects();
108
for ( size_t i=0; i < pProjectsArray->GetCount(); ++i )
110
AddProjectFiles(m_FilePaths, *pProjectsArray->Item(i));
111
if ( TestDestroy() == true ) return 0;
114
else if ( m_FindData.MustSearchInProject() == true )
116
// Search in project files ?
117
// Necessary only if not already parsed in worspace part
118
cbProject* pProject = Manager::Get()->GetProjectManager()->GetActiveProject();
119
if ( pProject != NULL )
121
AddProjectFiles(m_FilePaths, *pProject);
122
if ( TestDestroy() == true ) return 0;
125
else if ( m_FindData.MustSearchInTarget() == true )
127
// Search in target files ?
128
// Necessary only if not already parsed in project part
129
cbProject* pProject = Manager::Get()->GetProjectManager()->GetActiveProject();
130
if ( pProject != NULL )
132
ProjectBuildTarget *pTarget = pProject->GetBuildTarget(pProject->GetActiveBuildTarget());
135
AddTargetFiles(m_FilePaths, *pTarget);
136
if ( TestDestroy() == true ) return 0;
141
// Tests thread stop (cancel search, app shutdown)
142
if ( TestDestroy() == true ) return 0;
145
if ( m_FindData.MustSearchInOpenFiles() == true )
147
EditorManager* pEdManager = Manager::Get()->GetEditorManager();
148
for (i = 0; i < (size_t)pEdManager->GetNotebook()->GetPageCount(); ++i)
150
cbEditor* pEditor = pEdManager->GetBuiltinEditor(i);
151
if ( pEditor != NULL )
153
AddNewItem(m_FilePaths, pEditor->GetFilename());
158
// Tests thread stop (cancel search, app shutdown)
159
if ( TestDestroy() == true ) return 0;
161
// if the list is empty, leave
162
if (m_FilePaths.GetCount() == 0)
164
//-cbMessageBox(wxT("No files to search in!"), wxT("Error"), wxICON_WARNING);
165
////(pecan 2008/4/26)
166
// DO NOT issue graphics calls from this thread !!!!!!
167
ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
168
event.SetString(_("No files to search.\nCheck options "));
169
// Using wxPostEvent, we avoid multi-threaded memory violation.
170
wxPostEvent(m_pThreadSearchView,event);
174
for ( i = 0; i < m_FilePaths.GetCount(); ++i )
176
FindInFile(m_FilePaths[i]);
178
// Tests thread stop (cancel search, app shutdown)
179
if ( TestDestroy() == true ) return 0;
159
186
void ThreadSearchThread::OnExit()
161
// Method is called automatically by wxWidgets framework
162
// We inform thread caller about its termination.
163
m_pThreadSearchView->OnThreadExit();
188
// Method is called automatically by wxWidgets framework
189
// We inform thread caller about its termination.
190
m_pThreadSearchView->OnThreadExit();
167
194
wxDirTraverseResult ThreadSearchThread::OnDir(const wxString& WXUNUSED(dirName))
169
// Method is just used to test thread termination (user cancelled) and
170
// stop recursive dir traversing if it is not required.
171
if ( TestDestroy() == true )
175
return m_DefaultDirResult;
196
// Method is just used to test thread termination (user cancelled) and
197
// stop recursive dir traversing if it is not required.
198
if ( TestDestroy() == true )
202
return m_DefaultDirResult;
179
206
wxDirTraverseResult ThreadSearchThread::OnFile(const wxString& fileName)
181
// Tests thread termination (user cancelled)
182
if ( TestDestroy() == true )
187
// Looks if current file matches one of the file patterns
188
for (size_t i = 0; i < m_Masks.GetCount(); ++i)
190
if ( fileName.Matches(m_Masks[i].c_str() ) )
192
// Adds it to list of files to parse
193
m_FilePaths.Add(fileName);
198
return wxDIR_CONTINUE;
208
// Tests thread termination (user cancelled)
209
if ( TestDestroy() == true )
214
// Looks if current file matches one of the file patterns
215
for (size_t i = 0; i < m_Masks.GetCount(); ++i)
217
if ( fileName.Matches(m_Masks[i].c_str() ) )
219
// Adds it to list of files to parse
220
m_FilePaths.Add(fileName);
225
return wxDIR_CONTINUE;
202
229
void ThreadSearchThread::FindInFile(const wxString& path)
204
m_LineTextArray.Empty();
206
switch ( m_pTextFileSearcher->FindInFile(path, m_LineTextArray) )
208
case TextFileSearcher::idStringFound:
210
ThreadSearchEvent event(wxEVT_THREAD_SEARCH, -1);
211
event.SetString(path);
212
event.SetLineTextArray(m_LineTextArray);
214
// Using wxPostEvent, we avoid multi-threaded memory violation.
215
m_pThreadSearchView->PostThreadSearchEvent(event);
218
case TextFileSearcher::idStringNotFound:
222
case TextFileSearcher::idFileNotFound:
224
ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
225
event.SetString(path + _T(" does not exist."));
227
// Using wxPostEvent, we avoid multi-threaded memory violation.
228
wxPostEvent( m_pThreadSearchView,event);
231
case TextFileSearcher::idFileOpenError:
233
ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
234
event.SetString(_T("Failed to open ") + path);
236
// Using wxPostEvent, we avoid multi-threaded memory violation.
237
wxPostEvent( m_pThreadSearchView,event);
231
m_LineTextArray.Empty();
233
switch ( m_pTextFileSearcher->FindInFile(path, m_LineTextArray) )
235
case TextFileSearcher::idStringFound:
237
ThreadSearchEvent event(wxEVT_THREAD_SEARCH, -1);
238
event.SetString(path);
239
event.SetLineTextArray(m_LineTextArray);
241
// Using wxPostEvent, we avoid multi-threaded memory violation.
242
m_pThreadSearchView->PostThreadSearchEvent(event);
245
case TextFileSearcher::idStringNotFound:
249
case TextFileSearcher::idFileNotFound:
251
if(m_ShowFileMissingError)
253
ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
254
event.SetString(path + _(" does not exist."));
256
// Using wxPostEvent, we avoid multi-threaded memory violation.
257
wxPostEvent( m_pThreadSearchView,event);
261
case TextFileSearcher::idFileOpenError:
263
if(m_ShowCantOpenFileError)
265
ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
266
event.SetString(_("Failed to open ") + path);
268
// Using wxPostEvent, we avoid multi-threaded memory violation.
269
wxPostEvent( m_pThreadSearchView,event);
247
280
bool ThreadSearchThread::AddNewItem(wxSortedArrayString& sortedArrayString, const wxString& newItem)
249
// Adds item to array only if it does not exist
251
if ( sortedArrayString.Index(newItem.c_str()) == wxNOT_FOUND )
253
sortedArrayString.Add(newItem);
282
// Adds item to array only if it does not exist
284
if ( sortedArrayString.Index(newItem.c_str()) == wxNOT_FOUND )
286
sortedArrayString.Add(newItem);
260
293
void ThreadSearchThread::AddProjectFiles(wxSortedArrayString& sortedArrayString, cbProject& project)
262
// Adds project file paths to array only if they do not already exist.
263
// Same path may exist if we parse both open files and project files
265
for ( int i = 0; i < project.GetFilesCount(); ++i )
267
AddNewItem(sortedArrayString, project.GetFile(i)->file.GetFullPath());
268
if ( TestDestroy() == true ) return;
295
// Adds project file paths to array only if they do not already exist.
296
// Same path may exist if we parse both open files and project files
298
for ( int i = 0; i < project.GetFilesCount(); ++i )
300
AddNewItem(sortedArrayString, project.GetFile(i)->file.GetFullPath());
301
if ( TestDestroy() == true ) return;
306
void ThreadSearchThread::AddTargetFiles(wxSortedArrayString& sortedArrayString, ProjectBuildTarget& target)
308
// Adds target file paths to array only if they do not already exist.
309
// Same path may exist if we parse both open files and target files
311
for (FilesList::Node* it = target.GetFilesList().GetFirst(); it; it = it->GetNext())
313
ProjectFile* pf = it->GetData();
314
AddNewItem(sortedArrayString, pf->file.GetFullPath());
315
if ( TestDestroy() == true ) return;