Merge remote-tracking branch 'origin/master'
diff --git a/filesystemwatcher/README.md b/filesystemwatcher/README.md
new file mode 100644
index 0000000..da229ca
--- /dev/null
+++ b/filesystemwatcher/README.md
@@ -0,0 +1,65 @@
+Overview:
+
+FileSystemWatcher reports changes that are made to a monitored directory by signaling a registered callback function and passing that function a list of changes that have occurred. Each element of the list represents a file and the action that was performed on that file.
+
+Example:
+
+ ADDED: /Users/jared/Desktop/test.txt
+
+The list is held in a vector of type sEventInfo, where sEventInfo is a struct defined as follows:
+
+ enum eEvent {
+ ADDED = 0,
+ MODIFIED,
+ DELETED
+ };
+
+ struct sEventInfo {
+ eEvent event;
+ std::string absFilePath;
+ };
+
+The eEvent enumerator specifies the action taken on the file and the string absFilePath is the absolute file path of the file.
+
+Usage:
+
+SimpleEventCatcher is a dummy class that serves as an example of how to register for signals from FileSystemWatcher. These are the basic steps:
+
+ // invoke file system watcher on specified path
+ FileSystemWatcher watcher("/Users/jared/Desktop");
+
+ // pass the instance of FileSystemWatcher to the class
+ // that will register for event notifications
+ SimpleEventCatcher dirEventCatcher(&watcher);
+
+ // register for directory event signal (callback function)
+ QObject::connect(watcher, SIGNAL(dirEventSignal(std::vector<sEventInfo>)), this,
+ SLOT(handleDirEvent(std::vector<sEventInfo>)));
+
+ // implement handleDirEvent
+ void SimpleEventCatcher::handleDirEvent(std::vector<sEventInfo>)
+ {
+ /* implementation here */
+ }
+
+Debug:
+
+The debug flag can be set in filesystemwatcher.h. It is set to 1 by default and outputs the following information to the console:
+
+[BOOTSTRAP]
+
+[TIMER] Triggered Path: "/Users/jared/Desktop"
+ "ADDED: /Users/jared/Desktop/test2.txt"
+ "ADDED: /Users/jared/Desktop/test.txt"
+
+[SIGNAL] From SimpleEventCatcher Slot:
+ "ADDED: /Users/jared/Desktop/test2.txt"
+ "ADDED: /Users/jared/Desktop/test.txt"
+
+[\BOOTSTRAP]
+
+[WATCHER] Triggered Path: "/Users/jared/Desktop"
+ "DELETED: /Users/jared/Desktop/test2.txt"
+
+[SIGNAL] From SimpleEventCatcher Slot:
+ "DELETED: /Users/jared/Desktop/test2.txt"
diff --git a/filesystemwatcher/filesystemwatcher.cpp b/filesystemwatcher/filesystemwatcher.cpp
index c0fd350..b887292 100644
--- a/filesystemwatcher/filesystemwatcher.cpp
+++ b/filesystemwatcher/filesystemwatcher.cpp
@@ -1,57 +1,105 @@
-#include "filesystemwatcher.h"
-#include "ui_filesystemwatcher.h"
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ */
-filesystemwatcher::filesystemwatcher(QString dirPath, QWidget *parent) :
- QMainWindow(parent),
- m_ui(new Ui::filesystemwatcher),
+#include "filesystemwatcher.h"
+
+FileSystemWatcher::FileSystemWatcher(QString dirPath, QObject* parent) :
+ QObject(parent),
m_watcher(new QFileSystemWatcher()),
- m_listViewModel(new QStringListModel()),
- m_listView(new QListView()),
+ m_timer(new QTimer()),
m_dirPath(dirPath)
{
- // setup user interface
- m_ui->setupUi(this);
-
// add main directory to monitor
m_watcher->addPath(m_dirPath);
- // create the view
- m_listView->setModel(m_listViewModel);
- setCentralWidget(m_listView);
-
- // set title
- setWindowTitle("ChronoShare");
-
// register signals (callback functions)
- connect(m_watcher,SIGNAL(fileChanged(QString)),this,SLOT(fileChangedSlot(QString)));
- connect(m_watcher,SIGNAL(directoryChanged(QString)),this,SLOT(dirChangedSlot(QString)));
+ connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherCallbackSlot(QString)));
+ connect(m_timer, SIGNAL(timeout()), this, SLOT(timerCallbackSlot()));
- // bootstrap file list
- dirChangedSlot(m_dirPath);
+ // bootstrap
+ QTimer::singleShot(1000, this, SLOT(bootstrap()));
+
+ // start timer
+ m_timer->start(300000);
}
-filesystemwatcher::~filesystemwatcher()
+FileSystemWatcher::~FileSystemWatcher()
{
// clean up
- delete m_ui;
delete m_watcher;
- delete m_listViewModel;
- delete m_listView;
+ delete m_timer;
}
-void filesystemwatcher::fileChangedSlot(QString filePath)
+void FileSystemWatcher::bootstrap()
{
- QStringList fileList;
- fileList.append(filePath);
+ // bootstrap specific steps
+#if DEBUG
+ qDebug() << endl << "[BOOTSTRAP]";
+#endif
+ timerCallbackSlot();
+#if DEBUG
+ qDebug() << endl << "[\\BOOTSTRAP]";
+#endif
}
-void filesystemwatcher::dirChangedSlot(QString dirPath)
+void FileSystemWatcher::watcherCallbackSlot(QString dirPath)
{
+ // watcher specific steps
+#if DEBUG
+ qDebug() << endl << "[WATCHER] Triggered Path: " << dirPath;
+#endif
+ handleCallback(dirPath);
+}
+
+void FileSystemWatcher::timerCallbackSlot()
+{
+ // timer specific steps
+#if DEBUG
+ qDebug() << endl << "[TIMER] Triggered Path: " << m_dirPath;
+#endif
+ handleCallback(m_dirPath);
+}
+
+void FileSystemWatcher::handleCallback(QString dirPath)
+{
+ // scan directory and populate file list
+ QHash<QString, qint64> currentState = scanDirectory(dirPath);
+
+ // reconcile directory and report changes
+ std::vector<sEventInfo> dirChanges = reconcileDirectory(currentState, dirPath);
+#if DEBUG
+ // DEBUG: Print Changes
+ printChanges(dirChanges);
+#endif
+ // emit the signal if not empty
+ if(!dirChanges.empty())
+ emit dirEventSignal(dirChanges);
+}
+
+QHash<QString, qint64> FileSystemWatcher::scanDirectory(QString dirPath)
+{
// list of files in directory
- QStringList fileList;
+ QHash<QString, qint64> currentState;
// directory iterator (recursive)
- QDirIterator dirIterator(m_dirPath, QDirIterator::Subdirectories |
+ QDirIterator dirIterator(dirPath, QDirIterator::Subdirectories |
QDirIterator::FollowSymlinks);
// iterate through directory recursively
@@ -66,28 +114,155 @@
// if not this directory or previous directory
if(fileInfo.absoluteFilePath() != ".." && fileInfo.absoluteFilePath() != ".")
{
+ QString absFilePath = fileInfo.absoluteFilePath();
+
// if this is a directory
if(fileInfo.isDir())
{
QStringList dirList = m_watcher->directories();
// if the directory is not already being watched
- if (!dirList.contains(fileInfo.absoluteFilePath()))
+ if (absFilePath.startsWith(m_dirPath) && !dirList.contains(absFilePath))
{
// add this directory to the watch list
- m_watcher->addPath(fileInfo.absoluteFilePath());
+ m_watcher->addPath(absFilePath);
}
}
else
{
// add this file to the file list
- fileList.append(fileInfo.absoluteFilePath());
+ currentState.insert(absFilePath, fileInfo.created().toMSecsSinceEpoch());
}
}
}
- // update gui with list of files in this directory
- m_listViewModel->setStringList(fileList);
+ return currentState;
+}
+
+std::vector<sEventInfo> FileSystemWatcher::reconcileDirectory(QHash<QString, qint64> currentState, QString dirPath)
+{
+ // list of files changed
+ std::vector<sEventInfo> dirChanges;
+
+ // compare result (database/stored snapshot) to fileList (current snapshot)
+ QMutableHashIterator<QString, qint64> i(m_storedState);
+
+ while(i.hasNext())
+ {
+ i.next();
+
+ QString absFilePath = i.key();
+ qint64 storedCreated = i.value();
+
+ // if this file is in a level higher than
+ // this directory, ignore
+ if(!absFilePath.startsWith(dirPath))
+ {
+ continue;
+ }
+
+ // check file existence
+ if(currentState.contains(absFilePath))
+ {
+ qint64 currentCreated = currentState.value(absFilePath);
+
+ if(storedCreated != currentCreated)
+ {
+ // update stored state
+ i.setValue(currentCreated);
+
+ // this file has been modified
+ sEventInfo eventInfo;
+ eventInfo.event = MODIFIED;
+ eventInfo.absFilePath = absFilePath.toStdString();
+ dirChanges.push_back(eventInfo);
+ }
+
+ // delete this file from fileList we have processed it
+ currentState.remove(absFilePath);
+ }
+ else
+ {
+ // delete from stored state
+ i.remove();
+
+ // this file has been deleted
+ sEventInfo eventInfo;
+ eventInfo.event = DELETED;
+ eventInfo.absFilePath = absFilePath.toStdString();
+ dirChanges.push_back(eventInfo);
+ }
+ }
+
+ // any files left in fileList have been added
+ for(QHash<QString, qint64>::iterator i = currentState.begin(); i != currentState.end(); ++i)
+ {
+ QString absFilePath = i.key();
+ qint64 currentCreated = i.value();
+
+ m_storedState.insert(absFilePath, currentCreated);
+
+ // this file has been added
+ sEventInfo eventInfo;
+ eventInfo.event = ADDED;
+ eventInfo.absFilePath = absFilePath.toStdString();
+ dirChanges.push_back(eventInfo);
+ }
+
+ return dirChanges;
+}
+
+QByteArray FileSystemWatcher::calcChecksum(QString absFilePath)
+{
+ // initialize checksum
+ QCryptographicHash crypto(QCryptographicHash::Md5);
+
+ // open file
+ QFile file(absFilePath);
+ file.open(QFile::ReadOnly);
+
+ // calculate checksum
+ while(!file.atEnd())
+ {
+ crypto.addData(file.read(8192));
+ }
+
+ return crypto.result();
+}
+
+void FileSystemWatcher::printChanges(std::vector<sEventInfo> dirChanges)
+{
+ if(!dirChanges.empty())
+ {
+ for(size_t i = 0; i < dirChanges.size(); i++)
+ {
+ QString tempString;
+
+ eEvent event = dirChanges[i].event;
+ QString absFilePath = QString::fromStdString(dirChanges[i].absFilePath);
+
+ switch(event)
+ {
+ case ADDED:
+ tempString.append("ADDED: ");
+ break;
+ case MODIFIED:
+ tempString.append("MODIFIED: ");
+ break;
+ case DELETED:
+ tempString.append("DELETED: ");
+ break;
+ }
+
+ tempString.append(absFilePath);
+
+ qDebug() << "\t" << tempString;
+ }
+ }
+ else
+ {
+ qDebug() << "\t[EMPTY]";
+ }
}
#if WAF
diff --git a/filesystemwatcher/filesystemwatcher.h b/filesystemwatcher/filesystemwatcher.h
index d4ed8b6..543fba6 100644
--- a/filesystemwatcher/filesystemwatcher.h
+++ b/filesystemwatcher/filesystemwatcher.h
@@ -1,36 +1,84 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ */
#ifndef FILESYSTEMWATCHER_H
#define FILESYSTEMWATCHER_H
-#include <QtGui>
+#include <QFileSystemWatcher>
+#include <QCryptographicHash>
+#include <QDirIterator>
+#include <QFileInfo>
+#include <QDateTime>
+#include <QTimer>
+#include <QDebug>
+#include <QHash>
+#include <structs.h>
-namespace Ui {
-class filesystemwatcher;
-}
+#define DEBUG 1
-class filesystemwatcher : public QMainWindow
+class FileSystemWatcher : public QObject
{
Q_OBJECT
-
+
public:
// constructor
- filesystemwatcher(QString dirPath, QWidget *parent = 0);
+ FileSystemWatcher(QString dirPath, QObject* parent = 0);
// destructor
- ~filesystemwatcher();
+ ~FileSystemWatcher();
+
+signals:
+ // directory event signal
+ void dirEventSignal(std::vector<sEventInfo> dirChanges);
private slots:
- // signal for changes to monitored files
- void fileChangedSlot(QString filePath);
+ // handle callback from watcher
+ void watcherCallbackSlot(QString dirPath);
- // signal for changes to monitored directories
- void dirChangedSlot(QString dirPath);
-
+ // handle callback from timer
+ void timerCallbackSlot();
+
+ // bootstrap
+ void bootstrap();
+
private:
- Ui::filesystemwatcher* m_ui; // user interface
+ // handle callback from either the watcher or timer
+ void handleCallback(QString dirPath);
+
+ // scan directory and populate file list
+ QHash<QString, qint64> scanDirectory(QString dirPath);
+
+ // reconcile directory, find changes
+ std::vector<sEventInfo> reconcileDirectory(QHash<QString, qint64> fileList, QString dirPath);
+
+ // calculate checksum
+ QByteArray calcChecksum(QString absFilePath);
+
+ // print Changes (DEBUG)
+ void printChanges(std::vector<sEventInfo> dirChanges);
+
+private:
QFileSystemWatcher* m_watcher; // filesystem watcher
- QStringListModel* m_listViewModel; // list view model
- QListView* m_listView; // list
+ QTimer* m_timer; // timer
+
QString m_dirPath; // monitored path
+ QHash<QString, qint64> m_storedState; // stored state of directory
};
#endif // FILESYSTEMWATCHER_H
diff --git a/filesystemwatcher/filesystemwatcher.pro.user b/filesystemwatcher/filesystemwatcher.pro.user
deleted file mode 100644
index b69fc9e..0000000
--- a/filesystemwatcher/filesystemwatcher.pro.user
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE QtCreatorProject>
-<!-- Written by Qt Creator 2.6.0, 2013-01-09T00:05:54. -->
-<qtcreator>
- <data>
- <variable>ProjectExplorer.Project.ActiveTarget</variable>
- <value type="int">0</value>
- </data>
- <data>
- <variable>ProjectExplorer.Project.EditorSettings</variable>
- <valuemap type="QVariantMap">
- <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
- <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
- <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
- <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
- <value type="QString" key="language">Cpp</value>
- <valuemap type="QVariantMap" key="value">
- <value type="QString" key="CurrentPreferences">CppGlobal</value>
- </valuemap>
- </valuemap>
- <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
- <value type="QString" key="language">QmlJS</value>
- <valuemap type="QVariantMap" key="value">
- <value type="QString" key="CurrentPreferences">QmlJSGlobal</value>
- </valuemap>
- </valuemap>
- <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
- <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
- <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
- <value type="int" key="EditorConfiguration.IndentSize">4</value>
- <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
- <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
- <value type="int" key="EditorConfiguration.PaddingMode">1</value>
- <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
- <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
- <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
- <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
- <value type="int" key="EditorConfiguration.TabSize">8</value>
- <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
- <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
- <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
- <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
- <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
- <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
- </valuemap>
- </data>
- <data>
- <variable>ProjectExplorer.Project.PluginSettings</variable>
- <valuemap type="QVariantMap"/>
- </data>
- <data>
- <variable>ProjectExplorer.Project.Target.0</variable>
- <valuemap type="QVariantMap">
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">{ec4ff4f3-f12d-4e42-870d-b8c64ad3c1a3}</value>
- <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
- <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
- <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
- <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
- <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
- <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
- <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
- <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
- <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
- </valuemap>
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
- <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
- <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
- </valuemap>
- <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
- </valuemap>
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
- <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
- <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
- </valuemap>
- <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
- </valuemap>
- <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
- <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
- <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
- <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
- <value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/Users/jared/Documents/chronoshare/build/filesystemwatcher</value>
- <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
- </valuemap>
- <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
- <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
- <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
- <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
- <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
- <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
- </valuemap>
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
- <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
- <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
- </valuemap>
- <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
- </valuemap>
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
- <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
- <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
- <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
- </valuemap>
- <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
- </valuemap>
- <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
- <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
- <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
- <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
- <value type="QString" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory">/Users/jared/Documents/chronoshare/build/filesystemwatcher</value>
- <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
- </valuemap>
- <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
- <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
- <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
- <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
- </valuemap>
- <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
- </valuemap>
- <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
- <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
- <value type="bool" key="Analyzer.Project.UseGlobal">true</value>
- <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
- <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
- <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
- <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
- <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
- <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
- <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
- <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
- <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
- <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
- <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
- <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
- <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
- <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
- <value type="int">0</value>
- <value type="int">1</value>
- <value type="int">2</value>
- <value type="int">3</value>
- <value type="int">4</value>
- <value type="int">5</value>
- <value type="int">6</value>
- <value type="int">7</value>
- <value type="int">8</value>
- <value type="int">9</value>
- <value type="int">10</value>
- <value type="int">11</value>
- <value type="int">12</value>
- <value type="int">13</value>
- <value type="int">14</value>
- </valuelist>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">filesystemwatcher</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
- <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/Users/jared/Documents/chronoshare/filesystemwatcher/filesystemwatcher.pro</value>
- <value type="int" key="Qt4ProjectManager.Qt4RunConfiguration.BaseEnvironmentBase">2</value>
- <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
- <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">filesystemwatcher.pro</value>
- <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
- <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
- <valuelist type="QVariantList" key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges"/>
- <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
- <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
- <value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
- <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
- <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
- <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
- </valuemap>
- <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
- </valuemap>
- </data>
- <data>
- <variable>ProjectExplorer.Project.TargetCount</variable>
- <value type="int">1</value>
- </data>
- <data>
- <variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
- <value type="QString">{b042c0d4-4358-4d33-867e-7a86081b2fe9}</value>
- </data>
- <data>
- <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
- <value type="int">12</value>
- </data>
-</qtcreator>
diff --git a/filesystemwatcher/filesystemwatcher.ui b/filesystemwatcher/filesystemwatcher.ui
deleted file mode 100644
index 1c5e766..0000000
--- a/filesystemwatcher/filesystemwatcher.ui
+++ /dev/null
@@ -1,24 +0,0 @@
-<ui version="4.0">
- <class>filesystemwatcher</class>
- <widget class="QMainWindow" name="filesystemwatcher" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>300</height>
- </rect>
- </property>
- <property name="windowTitle" >
- <string>filesystemwatcher</string>
- </property>
- <widget class="QMenuBar" name="menuBar" />
- <widget class="QToolBar" name="mainToolBar" />
- <widget class="QWidget" name="centralWidget" />
- <widget class="QStatusBar" name="statusBar" />
- </widget>
- <layoutDefault spacing="6" margin="11" />
- <pixmapfunction></pixmapfunction>
- <resources/>
- <connections/>
-</ui>
diff --git a/filesystemwatcher/main.cpp b/filesystemwatcher/main.cpp
index dc2bc85..213a27e 100644
--- a/filesystemwatcher/main.cpp
+++ b/filesystemwatcher/main.cpp
@@ -1,13 +1,37 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ */
+
#include "filesystemwatcher.h"
+#include "simpleeventcatcher.h"
#include <QApplication>
+#include <iostream>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// invoke file system watcher on specified path
- filesystemwatcher watcher("/Users/jared/Desktop");
- watcher.show();
-
+ FileSystemWatcher watcher("/Users/jared/Desktop");
+
+ // class that will utilize these signals
+ SimpleEventCatcher dirEventCatcher(&watcher);
+
return app.exec();
}
diff --git a/filesystemwatcher/simpleeventcatcher.cpp b/filesystemwatcher/simpleeventcatcher.cpp
new file mode 100644
index 0000000..f1061fb
--- /dev/null
+++ b/filesystemwatcher/simpleeventcatcher.cpp
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ */
+
+#include "simpleeventcatcher.h"
+
+SimpleEventCatcher::SimpleEventCatcher(FileSystemWatcher* watcher, QObject *parent) :
+ QObject(parent)
+{
+ // register for directory event signal (callback function)
+ QObject::connect(watcher, SIGNAL(dirEventSignal(std::vector<sEventInfo>)), this, SLOT(handleDirEvent(std::vector<sEventInfo>)));
+}
+
+void SimpleEventCatcher::handleDirEvent(std::vector<sEventInfo> dirChanges)
+{
+ qDebug() << endl << "[SIGNAL] From SimpleEventCatcher Slot:";
+
+ if(!dirChanges.empty())
+ {
+ for(size_t i = 0; i < dirChanges.size(); i++)
+ {
+ QString tempString;
+
+ eEvent event = dirChanges[i].event;
+ QString absFilePath = QString::fromStdString(dirChanges[i].absFilePath);
+
+ switch(event)
+ {
+ case ADDED:
+ tempString.append("ADDED: ");
+ break;
+ case MODIFIED:
+ tempString.append("MODIFIED: ");
+ break;
+ case DELETED:
+ tempString.append("DELETED: ");
+ break;
+ }
+
+ tempString.append(absFilePath);
+
+ qDebug() << "\t" << tempString;
+ }
+ }
+ else
+ {
+ qDebug() << "\t[EMPTY]";
+ }
+}
+
+#if WAF
+#include "simpleeventcatcher.moc"
+#include "simpleeventcatcher.cpp.moc"
+#endif
diff --git a/filesystemwatcher/simpleeventcatcher.h b/filesystemwatcher/simpleeventcatcher.h
new file mode 100644
index 0000000..2a858fd
--- /dev/null
+++ b/filesystemwatcher/simpleeventcatcher.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ */
+
+#ifndef SIMPLEEVENTCATCHER_H
+#define SIMPLEEVENTCATCHER_H
+
+#include "filesystemwatcher.h"
+#include <QObject>
+#include <QDebug>
+#include <vector>
+#include <structs.h>
+
+class SimpleEventCatcher : public QObject
+{
+ Q_OBJECT
+public:
+ explicit SimpleEventCatcher(FileSystemWatcher* watcher, QObject *parent = 0);
+
+public slots:
+ // handle signal
+ void handleDirEvent(std::vector<sEventInfo> dirChanges);
+};
+
+#endif // SIMPLEEVENTCATCHER_H
diff --git a/filesystemwatcher/structs.h b/filesystemwatcher/structs.h
new file mode 100644
index 0000000..93008b1
--- /dev/null
+++ b/filesystemwatcher/structs.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jared Lindblom <lindblom@cs.ucla.edu>
+ */
+
+#ifndef STRUCTS_H
+#define STRUCTS_H
+
+enum eEvent {
+ ADDED = 0,
+ MODIFIED,
+ DELETED
+};
+
+struct sEventInfo {
+ eEvent event;
+ std::string absFilePath;
+};
+
+#endif // STRUCTS_H
diff --git a/wscript b/wscript
index 449ad2f..6872b0b 100644
--- a/wscript
+++ b/wscript
@@ -137,10 +137,10 @@
qt = bld (
- target = "gui",
+ target = "filewatcher",
features = "qt4 cxx cxxprogram",
defines = "WAF",
- source = "filesystemwatcher/filesystemwatcher.cpp filesystemwatcher/filesystemwatcher.ui filesystemwatcher/main.cpp",
+ source = "filesystemwatcher/filesystemwatcher.cpp filesystemwatcher/simpleeventcatcher.cpp filesystemwatcher/main.cpp",
includes = "filesystemwatcher src include .",
use = "QTCORE QTGUI"
)