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"
         )