initial commit
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
567
libs/wxWidgets-3.3.1/samples/fswatcher/fswatcher.cpp
Normal file
567
libs/wxWidgets-3.3.1/samples/fswatcher/fswatcher.cpp
Normal file
@@ -0,0 +1,567 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: samples/fswatcher/fswatcher.cpp
|
||||
// Purpose: wxFileSystemWatcher sample
|
||||
// Author: Bartosz Bekier
|
||||
// Created: 2009-06-27
|
||||
// Copyright: (c) Bartosz Bekier
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#ifndef wxHAS_IMAGES_IN_RESOURCES
|
||||
#include "../sample.xpm"
|
||||
#endif
|
||||
|
||||
#include "wx/fswatcher.h"
|
||||
#include "wx/listctrl.h"
|
||||
#include "wx/cmdline.h"
|
||||
|
||||
// Define a new frame type: this is going to be our main frame
|
||||
class MyFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MyFrame(const wxString& title);
|
||||
virtual ~MyFrame();
|
||||
|
||||
// Add an entry of the specified type asking the user for the filename if
|
||||
// the one passed to this function is empty.
|
||||
void AddEntry(wxFSWPathType type, wxString filename = wxString());
|
||||
|
||||
bool CreateWatcherIfNecessary();
|
||||
|
||||
private:
|
||||
// file system watcher creation
|
||||
void CreateWatcher();
|
||||
|
||||
// event handlers
|
||||
void OnClear(wxCommandEvent& WXUNUSED(event)) { m_evtConsole->Clear(); }
|
||||
void OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); }
|
||||
void OnWatch(wxCommandEvent& event);
|
||||
void OnFollowLinks(wxCommandEvent& event);
|
||||
void OnAbout(wxCommandEvent& event);
|
||||
|
||||
void OnAdd(wxCommandEvent& event);
|
||||
void OnAddTree(wxCommandEvent& event);
|
||||
void OnRemove(wxCommandEvent& event);
|
||||
void OnRemoveAll(wxCommandEvent& WXUNUSED(event));
|
||||
void OnRemoveUpdateUI(wxUpdateUIEvent& event);
|
||||
void OnRemoveAllUpdateUI(wxUpdateUIEvent& event);
|
||||
|
||||
void OnFileSystemEvent(wxFileSystemWatcherEvent& event);
|
||||
void LogEvent(const wxFileSystemWatcherEvent& event);
|
||||
|
||||
wxTextCtrl *m_evtConsole; // events console
|
||||
wxListView *m_filesList; // list of watched paths
|
||||
wxFileSystemWatcher* m_watcher; // file system watcher
|
||||
bool m_followLinks; // should symlinks be dereferenced
|
||||
|
||||
const static wxString LOG_FORMAT; // how to format events
|
||||
};
|
||||
|
||||
const wxString MyFrame::LOG_FORMAT = " %-12s %-36s %-36s";
|
||||
|
||||
// Define a new application type, each program should derive a class from wxApp
|
||||
class MyApp : public wxApp
|
||||
{
|
||||
public:
|
||||
// 'Main program' equivalent: the program execution "starts" here
|
||||
virtual bool OnInit() override
|
||||
{
|
||||
if ( !wxApp::OnInit() )
|
||||
return false;
|
||||
|
||||
wxLog::AddTraceMask("EventSource");
|
||||
wxLog::AddTraceMask(wxTRACE_FSWATCHER);
|
||||
|
||||
// create the main application window
|
||||
m_frame = new MyFrame("File System Watcher wxWidgets App");
|
||||
|
||||
// If we returned false here, the application would exit immediately.
|
||||
return true;
|
||||
}
|
||||
|
||||
// create the file system watcher here, because it needs an active loop
|
||||
virtual void OnEventLoopEnter(wxEventLoopBase* WXUNUSED(loop)) override
|
||||
{
|
||||
if ( m_frame->CreateWatcherIfNecessary() )
|
||||
{
|
||||
if ( !m_dirToWatch.empty() )
|
||||
m_frame->AddEntry(wxFSWPath_Dir, m_dirToWatch);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnInitCmdLine(wxCmdLineParser& parser) override
|
||||
{
|
||||
wxApp::OnInitCmdLine(parser);
|
||||
parser.AddParam("directory to watch",
|
||||
wxCMD_LINE_VAL_STRING,
|
||||
wxCMD_LINE_PARAM_OPTIONAL);
|
||||
}
|
||||
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser& parser) override
|
||||
{
|
||||
if ( !wxApp::OnCmdLineParsed(parser) )
|
||||
return false;
|
||||
|
||||
if ( parser.GetParamCount() )
|
||||
m_dirToWatch = parser.GetParam();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
MyFrame *m_frame;
|
||||
|
||||
// The directory to watch if specified on the command line.
|
||||
wxString m_dirToWatch;
|
||||
};
|
||||
|
||||
// Create a new application object: this macro will allow wxWidgets to create
|
||||
// the application object during program execution (it's better than using a
|
||||
// static object for many reasons) and also declares the accessor function
|
||||
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
|
||||
// not wxApp)
|
||||
wxIMPLEMENT_APP(MyApp);
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
// frame constructor
|
||||
MyFrame::MyFrame(const wxString& title)
|
||||
: wxFrame(nullptr, wxID_ANY, title),
|
||||
m_watcher(nullptr), m_followLinks(false)
|
||||
{
|
||||
SetIcon(wxICON(sample));
|
||||
|
||||
// IDs for menu and buttons
|
||||
enum
|
||||
{
|
||||
MENU_ID_QUIT = wxID_EXIT,
|
||||
MENU_ID_CLEAR = wxID_CLEAR,
|
||||
MENU_ID_WATCH = 101,
|
||||
MENU_ID_DEREFERENCE,
|
||||
|
||||
BTN_ID_ADD = 200,
|
||||
BTN_ID_ADD_TREE,
|
||||
BTN_ID_REMOVE,
|
||||
BTN_ID_REMOVE_ALL
|
||||
};
|
||||
|
||||
// ================================================================
|
||||
// menu
|
||||
|
||||
// create a menu bar
|
||||
wxMenu *menuFile = new wxMenu;
|
||||
menuFile->Append(MENU_ID_CLEAR, "&Clear log\tCtrl-L");
|
||||
menuFile->AppendSeparator();
|
||||
menuFile->Append(MENU_ID_QUIT, "E&xit\tAlt-X", "Quit this program");
|
||||
|
||||
// "Watch" menu
|
||||
wxMenu *menuMon = new wxMenu;
|
||||
wxMenuItem* it = menuMon->AppendCheckItem(MENU_ID_WATCH, "&Watch\tCtrl-W");
|
||||
// started by default, because file system watcher is started by default
|
||||
it->Check(true);
|
||||
|
||||
#if defined(__UNIX__)
|
||||
// Let the user decide whether to dereference symlinks. If he makes the
|
||||
// wrong choice, asserts will occur if the symlink target is also watched
|
||||
it = menuMon->AppendCheckItem(MENU_ID_DEREFERENCE,
|
||||
"&Follow symlinks\tCtrl-F",
|
||||
_("If checked, dereference symlinks")
|
||||
);
|
||||
it->Check(false);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnFollowLinks, this, MENU_ID_DEREFERENCE);
|
||||
#endif // __UNIX__
|
||||
|
||||
// the "About" item should be in the help menu
|
||||
wxMenu *menuHelp = new wxMenu;
|
||||
menuHelp->Append(wxID_ABOUT, "&About\tF1", "Show about dialog");
|
||||
|
||||
// now append the freshly created menu to the menu bar...
|
||||
wxMenuBar *menuBar = new wxMenuBar();
|
||||
menuBar->Append(menuFile, "&File");
|
||||
menuBar->Append(menuMon, "&Watch");
|
||||
menuBar->Append(menuHelp, "&Help");
|
||||
|
||||
// ... and attach this menu bar to the frame
|
||||
SetMenuBar(menuBar);
|
||||
|
||||
// ================================================================
|
||||
// upper panel
|
||||
|
||||
// panel
|
||||
wxPanel *panel = new wxPanel(this);
|
||||
wxSizer *panelSizer = new wxGridSizer(2);
|
||||
wxBoxSizer *leftSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// label
|
||||
wxStaticText* label = new wxStaticText(panel, wxID_ANY, "Watched paths");
|
||||
leftSizer->Add(label, wxSizerFlags().Center().Border(wxALL));
|
||||
|
||||
// list of files
|
||||
m_filesList = new wxListView(panel, wxID_ANY, wxPoint(-1,-1),
|
||||
wxSize(300,200), wxLC_LIST | wxLC_SINGLE_SEL);
|
||||
leftSizer->Add(m_filesList, wxSizerFlags(1).Expand());
|
||||
|
||||
// buttons
|
||||
wxButton* buttonAdd = new wxButton(panel, BTN_ID_ADD, "&Add");
|
||||
wxButton* buttonAddTree = new wxButton(panel, BTN_ID_ADD_TREE, "Add &tree");
|
||||
wxButton* buttonRemove = new wxButton(panel, BTN_ID_REMOVE, "&Remove");
|
||||
wxButton* buttonRemoveAll = new wxButton(panel, BTN_ID_REMOVE_ALL, "Remove a&ll");
|
||||
wxSizer *btnSizer = new wxGridSizer(2);
|
||||
btnSizer->Add(buttonAdd, wxSizerFlags().Center().Border(wxALL));
|
||||
btnSizer->Add(buttonAddTree, wxSizerFlags().Center().Border(wxALL));
|
||||
btnSizer->Add(buttonRemove, wxSizerFlags().Center().Border(wxALL));
|
||||
btnSizer->Add(buttonRemoveAll, wxSizerFlags().Center().Border(wxALL));
|
||||
|
||||
// and put it all together
|
||||
leftSizer->Add(btnSizer, wxSizerFlags(0).Expand());
|
||||
panelSizer->Add(leftSizer, wxSizerFlags(1).Expand());
|
||||
panel->SetSizerAndFit(panelSizer);
|
||||
|
||||
// ================================================================
|
||||
// lower panel
|
||||
|
||||
wxTextCtrl *headerText = new wxTextCtrl(this, wxID_ANY, "",
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_READONLY);
|
||||
wxString h = wxString::Format(LOG_FORMAT, "event", "path", "new path");
|
||||
headerText->SetValue(h);
|
||||
|
||||
// event console
|
||||
m_evtConsole = new wxTextCtrl(this, wxID_ANY, "",
|
||||
wxDefaultPosition, wxSize(200,200),
|
||||
wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL);
|
||||
|
||||
// set monospace font to have output in nice columns
|
||||
wxFont font(wxFontInfo(9).Family(wxFONTFAMILY_TELETYPE));
|
||||
headerText->SetFont(font);
|
||||
m_evtConsole->SetFont(font);
|
||||
|
||||
// ================================================================
|
||||
// laying out whole frame
|
||||
|
||||
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->Add(panel, wxSizerFlags(1).Expand());
|
||||
sizer->Add(headerText, wxSizerFlags().Expand());
|
||||
sizer->Add(m_evtConsole, wxSizerFlags(1).Expand());
|
||||
SetSizerAndFit(sizer);
|
||||
|
||||
// set size and position on screen
|
||||
SetSize(800, 600);
|
||||
CentreOnScreen();
|
||||
|
||||
// ================================================================
|
||||
// event handlers & show
|
||||
|
||||
// menu
|
||||
Bind(wxEVT_MENU, &MyFrame::OnClear, this, MENU_ID_CLEAR);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnQuit, this, MENU_ID_QUIT);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnWatch, this, MENU_ID_WATCH);
|
||||
Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
|
||||
|
||||
// buttons
|
||||
Bind(wxEVT_BUTTON, &MyFrame::OnAdd, this, BTN_ID_ADD);
|
||||
Bind(wxEVT_BUTTON, &MyFrame::OnAddTree, this, BTN_ID_ADD_TREE);
|
||||
Bind(wxEVT_BUTTON, &MyFrame::OnRemove, this, BTN_ID_REMOVE);
|
||||
Bind(wxEVT_UPDATE_UI, &MyFrame::OnRemoveUpdateUI, this, BTN_ID_REMOVE);
|
||||
Bind(wxEVT_BUTTON, &MyFrame::OnRemoveAll, this, BTN_ID_REMOVE_ALL);
|
||||
Bind(wxEVT_UPDATE_UI, &MyFrame::OnRemoveAllUpdateUI, this, BTN_ID_REMOVE_ALL);
|
||||
|
||||
// and show itself (the frames, unlike simple controls, are not shown when
|
||||
// created initially)
|
||||
Show(true);
|
||||
}
|
||||
|
||||
MyFrame::~MyFrame()
|
||||
{
|
||||
delete m_watcher;
|
||||
}
|
||||
|
||||
bool MyFrame::CreateWatcherIfNecessary()
|
||||
{
|
||||
if (m_watcher)
|
||||
return false;
|
||||
|
||||
CreateWatcher();
|
||||
Bind(wxEVT_FSWATCHER, &MyFrame::OnFileSystemEvent, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MyFrame::CreateWatcher()
|
||||
{
|
||||
wxCHECK_RET(!m_watcher, "Watcher already initialized");
|
||||
m_watcher = new wxFileSystemWatcher();
|
||||
m_watcher->SetOwner(this);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// event handlers
|
||||
// ============================================================================
|
||||
|
||||
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxMessageBox("Demonstrates the usage of file system watcher, "
|
||||
"the wxWidgets monitoring system notifying you of "
|
||||
"changes done to your files.\n"
|
||||
"(c) 2009 Bartosz Bekier\n",
|
||||
"About wxWidgets File System Watcher Sample",
|
||||
wxOK | wxICON_INFORMATION, this);
|
||||
}
|
||||
|
||||
void MyFrame::OnWatch(wxCommandEvent& event)
|
||||
{
|
||||
wxLogDebug("%s start=%d", __func__, event.IsChecked());
|
||||
|
||||
if (event.IsChecked())
|
||||
{
|
||||
wxCHECK_RET(!m_watcher, "Watcher already initialized");
|
||||
CreateWatcher();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCHECK_RET(m_watcher, "Watcher not initialized");
|
||||
m_filesList->DeleteAllItems();
|
||||
wxDELETE(m_watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnFollowLinks(wxCommandEvent& event)
|
||||
{
|
||||
m_followLinks = event.IsChecked();
|
||||
}
|
||||
|
||||
void MyFrame::OnAdd(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
AddEntry(wxFSWPath_Dir);
|
||||
}
|
||||
|
||||
void MyFrame::OnAddTree(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
AddEntry(wxFSWPath_Tree);
|
||||
}
|
||||
|
||||
void MyFrame::AddEntry(wxFSWPathType type, wxString filename)
|
||||
{
|
||||
if ( filename.empty() )
|
||||
{
|
||||
// TODO account for adding the files as well
|
||||
filename = wxDirSelector("Choose a folder to watch", "",
|
||||
wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
|
||||
if ( filename.empty() )
|
||||
return;
|
||||
}
|
||||
|
||||
wxCHECK_RET(m_watcher, "Watcher not initialized");
|
||||
|
||||
wxLogDebug("Adding %s: '%s'",
|
||||
filename,
|
||||
type == wxFSWPath_Dir ? "directory" : "directory tree");
|
||||
|
||||
wxString prefix;
|
||||
bool ok = false;
|
||||
|
||||
// This will tell wxFileSystemWatcher whether to dereference symlinks
|
||||
wxFileName fn = wxFileName::DirName(filename);
|
||||
if (!m_followLinks)
|
||||
{
|
||||
fn.DontFollowLink();
|
||||
}
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case wxFSWPath_Dir:
|
||||
ok = m_watcher->Add(fn);
|
||||
prefix = "Dir: ";
|
||||
break;
|
||||
|
||||
case wxFSWPath_Tree:
|
||||
ok = m_watcher->AddTree(fn);
|
||||
prefix = "Tree: ";
|
||||
break;
|
||||
|
||||
case wxFSWPath_File:
|
||||
case wxFSWPath_None:
|
||||
wxFAIL_MSG( "Unexpected path type." );
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
wxLogError("Error adding '%s' to watched paths", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepend 'prefix' to the filepath, partly for display
|
||||
// but mostly so that OnRemove() can work out the correct way to remove it
|
||||
m_filesList->InsertItem(m_filesList->GetItemCount(),
|
||||
prefix + wxFileName::DirName(filename).GetFullPath());
|
||||
}
|
||||
|
||||
void MyFrame::OnRemove(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxCHECK_RET(m_watcher, "Watcher not initialized");
|
||||
long idx = m_filesList->GetFirstSelected();
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
bool ret = false;
|
||||
wxString path = m_filesList->GetItemText(idx).Mid(6);
|
||||
|
||||
// This will tell wxFileSystemWatcher whether to dereference symlinks
|
||||
wxFileName fn = wxFileName::DirName(path);
|
||||
if (!m_followLinks)
|
||||
{
|
||||
fn.DontFollowLink();
|
||||
}
|
||||
|
||||
// TODO we know it is a dir, but it doesn't have to be
|
||||
if (m_filesList->GetItemText(idx).StartsWith("Dir: "))
|
||||
{
|
||||
ret = m_watcher->Remove(fn);
|
||||
}
|
||||
else if (m_filesList->GetItemText(idx).StartsWith("Tree: "))
|
||||
{
|
||||
ret = m_watcher->RemoveTree(fn);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG("Unexpected item in wxListView.");
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
wxLogError("Error removing '%s' from watched paths", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filesList->DeleteItem(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnRemoveAll(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if ( !m_watcher->RemoveAll() )
|
||||
{
|
||||
wxLogError("Error removing all paths from watched paths");
|
||||
}
|
||||
|
||||
m_filesList->DeleteAllItems();
|
||||
}
|
||||
|
||||
void MyFrame::OnRemoveUpdateUI(wxUpdateUIEvent& event)
|
||||
{
|
||||
event.Enable(m_filesList->GetFirstSelected() != wxNOT_FOUND);
|
||||
}
|
||||
|
||||
void MyFrame::OnRemoveAllUpdateUI(wxUpdateUIEvent& event)
|
||||
{
|
||||
event.Enable( m_filesList->GetItemCount() != 0 );
|
||||
}
|
||||
|
||||
void MyFrame::OnFileSystemEvent(wxFileSystemWatcherEvent& event)
|
||||
{
|
||||
// TODO remove when code is rock-solid
|
||||
wxLogTrace(wxTRACE_FSWATCHER, "*** %s ***", event.ToString());
|
||||
LogEvent(event);
|
||||
|
||||
int type = event.GetChangeType();
|
||||
if ((type == wxFSW_EVENT_DELETE) || (type == wxFSW_EVENT_RENAME))
|
||||
{
|
||||
// If path is one of our watched dirs, we need to react to this
|
||||
// otherwise there'll be asserts if later we try to remove it
|
||||
wxString eventpath = event.GetPath().GetFullPath();
|
||||
bool found(false);
|
||||
for (size_t n = m_filesList->GetItemCount(); n > 0; --n)
|
||||
{
|
||||
wxString path;
|
||||
if ((!m_filesList->GetItemText(n-1).StartsWith("Dir: ", &path)) &&
|
||||
(!m_filesList->GetItemText(n-1).StartsWith("Tree: ", &path)))
|
||||
{
|
||||
wxFAIL_MSG("Unexpected item in wxListView.");
|
||||
}
|
||||
if (path == eventpath)
|
||||
{
|
||||
if (type == wxFSW_EVENT_DELETE)
|
||||
{
|
||||
m_filesList->DeleteItem(n-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// At least in wxGTK, we'll never get here: renaming the top
|
||||
// watched dir gives IN_MOVE_SELF and no new-name info.
|
||||
// However I'll leave the code in case other platforms do
|
||||
wxString newname = event.GetNewPath().GetFullPath();
|
||||
if (newname.empty() ||
|
||||
newname == event.GetPath().GetFullPath())
|
||||
{
|
||||
// Just in case either of these are possible...
|
||||
wxLogTrace(wxTRACE_FSWATCHER,
|
||||
"Invalid attempt to rename to %s", newname);
|
||||
return;
|
||||
}
|
||||
wxString prefix =
|
||||
m_filesList->GetItemText(n-1).StartsWith("Dir: ") ?
|
||||
"Dir: " : "Tree: ";
|
||||
m_filesList->SetItemText(n-1, prefix + newname);
|
||||
}
|
||||
found = true;
|
||||
// Don't break: a filepath may have been added more than once
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
"Your watched path %s has been deleted or renamed\n",
|
||||
eventpath);
|
||||
m_evtConsole->AppendText(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static wxString GetFSWEventChangeTypeName(int changeType)
|
||||
{
|
||||
switch (changeType)
|
||||
{
|
||||
case wxFSW_EVENT_CREATE:
|
||||
return "CREATE";
|
||||
case wxFSW_EVENT_DELETE:
|
||||
return "DELETE";
|
||||
case wxFSW_EVENT_RENAME:
|
||||
return "RENAME";
|
||||
case wxFSW_EVENT_MODIFY:
|
||||
return "MODIFY";
|
||||
case wxFSW_EVENT_ACCESS:
|
||||
return "ACCESS";
|
||||
case wxFSW_EVENT_ATTRIB: // Currently this is wxGTK-only
|
||||
return "ATTRIBUTE";
|
||||
#ifdef wxHAS_INOTIFY
|
||||
case wxFSW_EVENT_UNMOUNT: // Currently this is wxGTK-only
|
||||
return "UNMOUNT";
|
||||
#endif
|
||||
case wxFSW_EVENT_WARNING:
|
||||
return "WARNING";
|
||||
case wxFSW_EVENT_ERROR:
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
return "INVALID_TYPE";
|
||||
}
|
||||
|
||||
void MyFrame::LogEvent(const wxFileSystemWatcherEvent& event)
|
||||
{
|
||||
wxString entry = wxString::Format(LOG_FORMAT + "\n",
|
||||
GetFSWEventChangeTypeName(event.GetChangeType()),
|
||||
event.GetPath().GetFullPath(),
|
||||
event.GetNewPath().GetFullPath());
|
||||
m_evtConsole->AppendText(entry);
|
||||
}
|
||||
Reference in New Issue
Block a user