1
/***************************************************************
2
* Name: ThreadSearchLoggerList
3
* Purpose: ThreadSearchLoggerTree implements the
4
* ThreadSearchLoggerBase interface with a wxListCtrl.
5
* Author: Jerome ANTOINE
7
* Copyright: Jerome ANTOINE
9
**************************************************************/
11
#include <sdk.h> // Code::Blocks SDK
13
// Required extra includes
14
#include "configmanager.h"
17
#include <wx/listctrl.h>
18
#include <wx/dynarray.h>
20
#include "ThreadSearch.h"
21
#include "ThreadSearchView.h"
22
#include "ThreadSearchEvent.h"
23
#include "ThreadSearchLoggerList.h"
24
#include "ThreadSearchControlIds.h"
25
#include "snippetsconfig.h"
28
ThreadSearchLoggerList::ThreadSearchLoggerList(ThreadSearchView& threadSearchView,
29
ThreadSearch& threadSearchPlugin,
30
InsertIndexManager::eFileSorting fileSorting,
33
: ThreadSearchLoggerBase(threadSearchView, threadSearchPlugin, fileSorting)
35
m_pListLog = new wxListCtrl(pParent, id, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL|wxSUNKEN_BORDER);
36
m_pListLog->SetMinSize(wxSize(100,100));
40
// Events are managed dynamically to be able to stop/start management when required.
41
ConnectEvents(pParent);
45
// ----------------------------------------------------------------------------
46
ThreadSearchLoggerList::~ThreadSearchLoggerList()
47
// ----------------------------------------------------------------------------
49
wxWindow* pParent = m_pListLog->GetParent();
50
if ( pParent != NULL )
52
// Events are managed dynamically to be able to stop/start management when required.
53
DisconnectEvents(pParent);
56
// Memorize colume widths for next usage //(pecan 2008/5/22)
57
ConfigManager* pCfg = Manager::Get()->GetConfigManager(_T("SnippetsSearch"));
58
pCfg->Write(wxT("/LogColSizeDir"), m_pListLog->GetColumnWidth(0));
59
pCfg->Write(wxT("/LogColSizeFile"), m_pListLog->GetColumnWidth(1));
60
pCfg->Write(wxT("/LogColSizeLine"), m_pListLog->GetColumnWidth(2));
61
pCfg->Write(wxT("/LogColSizeText"), m_pListLog->GetColumnWidth(3));
63
m_pListLog->Destroy();
67
void ThreadSearchLoggerList::Update()
69
ThreadSearchLoggerBase::Update();
71
// Adds/Removes listview header and adds/removes vertical rules
72
m_pListLog->SetSingleStyle(wxLC_NO_HEADER, !m_ThreadSearchPlugin.GetDisplayLogHeaders());
73
m_pListLog->SetSingleStyle(wxLC_VRULES, m_ThreadSearchPlugin.GetDrawLogLines());
76
// ----------------------------------------------------------------------------
77
void ThreadSearchLoggerList::SetListColumns()
78
// ----------------------------------------------------------------------------
80
m_pListLog->ClearAll();
82
// Size columes set by last user usage //(pecan 2008/5/22)
83
ConfigManager* pCfg = Manager::Get()->GetConfigManager(_T("SnippetsSearch"));
84
int directoryColSize = pCfg->ReadInt(wxT("/LogColSizeDir"), 100);
85
int fileColSize = pCfg->ReadInt(wxT("/LogColSizeFile"), 100);
86
int lineColSize = pCfg->ReadInt(wxT("/LogColSizeLine"), 50);
87
int textColSize = pCfg->ReadInt(wxT("/LogColSizeText"), 500);
89
m_pListLog->InsertColumn(0, wxT("Directory"), wxLIST_FORMAT_LEFT, directoryColSize);
90
m_pListLog->InsertColumn(1, wxT("File"), wxLIST_FORMAT_LEFT, fileColSize);
91
m_pListLog->InsertColumn(2, wxT("Line"), wxLIST_FORMAT_RIGHT, lineColSize);
92
m_pListLog->InsertColumn(3, wxT("Text"), wxLIST_FORMAT_LEFT, textColSize);
94
// ----------------------------------------------------------------------------
95
void ThreadSearchLoggerList::OnMouseWheelEvent(wxMouseEvent& event)
96
// ----------------------------------------------------------------------------
98
// Ctrl-MouseWheel rotation changes treeCtrl font
99
//-wxWindow* pParent = m_pListLog->GetParent();
100
//wxWindow* pParent = (wxWindow*)event.GetEventObject();
101
wxWindow* pParent = m_pListLog;
102
if ( not pParent ) return;
104
bool mouseCtrlKeyDown = event.ControlDown();
106
//LOGIT(wxT("treeCtrl:OnMouseWheel[%s]"), m_MouseCtrlKeyDown?wxT("Down"):wxT("UP") );
108
if (not mouseCtrlKeyDown) {event.Skip(); return;}
110
int nRotation = event.GetWheelRotation();
111
wxFont ctrlFont = pParent->GetFont();
114
ctrlFont.SetPointSize( ctrlFont.GetPointSize()-1);
116
ctrlFont.SetPointSize( ctrlFont.GetPointSize()+1);
118
pParent->SetFont(ctrlFont);
123
// ----------------------------------------------------------------------------
124
void ThreadSearchLoggerList::OnLoggerListClick(wxListEvent& event)
125
// ----------------------------------------------------------------------------
127
// Manages list log left (single) click
128
// Gets file path and line from list control
130
//Ignore the right mouse key //(pecan 2008/4/25)
131
if ( ::wxGetMouseState().RightDown() )
133
// Ignore RightMouseSelect, put back last LeftMouseSelect
134
wxListCtrl* pListCtrl = (wxListCtrl*)event.GetEventObject();
135
pListCtrl->SetItemState(m_LastLeftMouseClickIndex, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
136
event.Skip(); return;
139
wxString filepath(wxEmptyString);
141
if ( GetFileLineFromListEvent(event, filepath, line) == false )
143
cbMessageBox(wxT("Failed to retrieve file path and line number"), wxT("Error"), wxICON_ERROR);
146
m_ThreadSearchView.OnLoggerClick(filepath, line);
147
m_LastLeftMouseClickIndex = event.GetIndex();
150
// ----------------------------------------------------------------------------
151
void ThreadSearchLoggerList::OnLoggerListDoubleClick(wxListEvent& event)
152
// ----------------------------------------------------------------------------
154
// Manages list log left double click
155
// Gets file path and line from list control
156
wxString filepath(wxEmptyString);
158
if ( GetFileLineFromListEvent(event, filepath, line) == false )
160
cbMessageBox(wxT("Failed to retrieve file path and line number"), wxT("Error"), wxICON_ERROR);
163
m_ThreadSearchView.OnLoggerDoubleClick(filepath, line);
168
bool ThreadSearchLoggerList::GetFileLineFromListEvent(wxListEvent& event, wxString& filepath, long &line)
170
bool success = false;
174
// Finds selected item index
175
long index = m_pListLog->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
176
if ( index == -1 ) break;
178
// First, gets file dir
180
listItem.m_itemId = index;
182
listItem.m_mask = wxLIST_MASK_TEXT;
184
if ( m_pListLog->GetItem(listItem) == false ) break;
186
filedir = listItem.GetText();
188
// Then build complete filename from dir and file
190
if ( m_pListLog->GetItem(listItem) == false ) break;
192
wxFileName sFile(filedir, listItem.GetText());
193
filepath = sFile.GetFullPath();
195
// Then gets line number
197
if ( m_pListLog->GetItem(listItem) == false ) break;
199
if ( listItem.GetText().ToLong(&line) == true )
207
// ----------------------------------------------------------------------------
208
void ThreadSearchLoggerList::OnThreadSearchEvent(const ThreadSearchEvent& event)
209
// ----------------------------------------------------------------------------
211
// A search event has been sent by the worker thread.
213
const wxArrayString& words = event.GetLineTextArray();
214
const wxFileName& filename(event.GetString());
215
bool setFocus(false);
217
wxString setFocusDir;
218
wxString setFocusFilename;
220
wxASSERT((words.GetCount() % 2) == 0);
222
// Use of Freeze Thaw to enhance speed and limit blink effect
223
m_pListLog->Freeze();
224
long index = m_IndexManager.GetInsertionIndex(filename.GetFullPath(), words.GetCount()/2);
225
for (size_t i = 0; i < words.GetCount(); i += 2)
227
m_pListLog->InsertItem(index, filename.GetPath()); // Directory
228
m_pListLog->SetItem(index, 1, filename.GetFullName()); // File name
229
m_pListLog->SetItem(index, 2, words[i]); // Line index starting from 1
230
m_pListLog->SetItem(index, 3, words[i+1]); // File line matching search expression
232
//(pecan 2008/7/31) Dont do the following here or Ctrl-MouseWheel cannot change the font size
233
//-m_pListLog->SetItemFont(index, m_ThreadSearchPlugin.m_Conf_font); //(pecan 2008/3/06)
235
// We update preview log for first list item
236
if ( m_pListLog->GetItemCount() == 1 )
240
if ( words[i].ToLong(&line) == false )
242
cbMessageBox(wxT("Failed to convert line number from %s") + words[i], wxT("Error"), wxICON_ERROR);
246
m_ThreadSearchView.UpdatePreview(filename.GetFullPath(), line);
248
// It is useful to give focus to list to navigate in results
249
// just after running a search
251
setFocusItem = index;
252
setFocusDir = filename.GetPath();
253
setFocusFilename = filename.GetFullName();
259
// Note: (pecan 2008/4/27)
260
// The wxListCtrl is not redrawn at this point. It's blank.
261
// This routine is driven from a timer interrupt. So the listCtrl
262
// will problably not update until events are exhausted.
263
// Doing a Yield() just causes crashes in event Processing.
264
//Manager::Yield(); <-- causes crash in queued event processing.
265
//See: SyncLoggerToPreview() called from OnTmrListCtrlUpdate
267
if ( setFocus == true )
269
// Select item so update view can find it later //(pecan 2008/4/27)
270
m_pListLog->SetItemState(setFocusItem, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
272
// On Linux, executing SetFocus just after UpdatePreview(0)
273
// does not work. Probbly because of Thaw...
274
m_pListLog->SetFocus();
279
wxWindow* ThreadSearchLoggerList::GetWindow()
285
// ----------------------------------------------------------------------------
286
void ThreadSearchLoggerList::SetFocus()
287
// ----------------------------------------------------------------------------
289
m_pListLog->SetFocus();
290
SyncLoggerToPreview();
292
// ----------------------------------------------------------------------------
293
void ThreadSearchLoggerList::ConnectEvents(wxEvtHandler* pEvtHandler)
294
// ----------------------------------------------------------------------------
296
// Dynamic event connections.
297
int id = m_pListLog->GetId();
298
pEvtHandler->Connect(id, wxEVT_COMMAND_LIST_ITEM_SELECTED,
299
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
300
&ThreadSearchLoggerList::OnLoggerListClick, NULL, static_cast<wxEvtHandler*>(this));
302
pEvtHandler->Connect(id, wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
303
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
304
&ThreadSearchLoggerList::OnLoggerListDoubleClick, NULL, static_cast<wxEvtHandler*>(this));
306
m_pListLog->Connect(id, wxEVT_MOUSEWHEEL, //(pecan 2008/7/31)
307
(wxObjectEventFunction)(wxEventFunction)(wxMouseEventFunction)
308
&ThreadSearchLoggerList::OnMouseWheelEvent, NULL, static_cast<wxEvtHandler*>(this));
312
void ThreadSearchLoggerList::DisconnectEvents(wxEvtHandler* pEvtHandler)
314
// Dynamic event Disconnections.
315
int id = m_pListLog->GetId();
316
pEvtHandler->Disconnect(id, wxEVT_COMMAND_LIST_ITEM_SELECTED,
317
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
318
&ThreadSearchLoggerList::OnLoggerListClick, NULL, static_cast<wxEvtHandler*>(this));
320
pEvtHandler->Disconnect(id, wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
321
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
322
&ThreadSearchLoggerList::OnLoggerListDoubleClick, NULL, static_cast<wxEvtHandler*>(this));
324
m_pListLog->Disconnect(id, wxEVT_MOUSEWHEEL, //(pecan 2008/7/31)
325
(wxObjectEventFunction)(wxEventFunction)(wxMouseEventFunction)
326
&ThreadSearchLoggerList::OnMouseWheelEvent, NULL, static_cast<wxEvtHandler*>(this));
331
void ThreadSearchLoggerList::Clear()
333
m_pListLog->DeleteAllItems();
334
m_IndexManager.Reset();
336
// ----------------------------------------------------------------------------
337
void ThreadSearchLoggerList::SyncLoggerToPreview()
338
// ----------------------------------------------------------------------------
339
{ //(pecan 2008/4/27)
340
// We need to position the Logger window to the selection
341
// in Preview cbEditor control.
342
// This routine must be called *after* the thread events have been
343
// exhausted (in the timer event) and the window has already been redrawn.
345
wxListCtrl* pListCtrl = (wxListCtrl*)GetWindow();
346
long setFocusItem = pListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
348
if (setFocusItem == -1) //no selecction
351
m_LastLeftMouseClickIndex = setFocusItem;
352
pListCtrl->EnsureVisible(setFocusItem);
353
pListCtrl->SetFocus();