Browse Source

first port to C++

Duncan Mac-Vicar P 15 years ago
commit
b7a3fc7ab8

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+build
+*flymake*
+

+ 6 - 0
CMakeLists.txt

@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8)
+project(mirall)
+
+find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtXml REQUIRED )
+add_subdirectory(src)
+

+ 17 - 0
src/CMakeLists.txt

@@ -0,0 +1,17 @@
+include_directories(${CMAKE_SOURCE_DIR}/src)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include(${QT_USE_FILE})
+
+set(mirall_SRCS
+mirall/application.cpp
+mirall/folder.cpp
+mirall/gitfolder.cpp
+mirall/folderwatcher.cpp
+main.cpp)
+
+qt4_automoc(${mirall_SRCS})
+
+add_executable(mirall ${mirall_SRCS})
+target_link_libraries(mirall ${QT_LIBRARIES})
+

+ 9 - 0
src/main.cpp

@@ -0,0 +1,9 @@
+
+#include "mirall/application.h"
+
+int main(int argc, char **argv)
+{
+  Mirall::Application app(argc, argv);
+  return app.exec();
+}
+

+ 61 - 0
src/mirall/application.cpp

@@ -0,0 +1,61 @@
+#include <QDebug>
+#include <QDir>
+#include <QIcon>
+#include <QMenu>
+#include <QSystemTrayIcon>
+
+#include "mirall/constants.h"
+#include "mirall/application.h"
+#include "mirall/folder.h"
+#include "mirall/gitfolder.h"
+
+namespace Mirall {
+
+Application::Application(int argc, char **argv) :
+    QApplication(argc, argv)
+{
+    _folder = new GitFolder(QDir::homePath() + "/Mirall", this);
+    setApplicationName("Mirall");
+    setupActions();
+    setupSystemTray();
+    setupContextMenu();
+}
+
+Application::~Application()
+{
+}
+
+void Application::setupActions()
+{
+    _actionAddFolder = new QAction(tr("Add folder"), this);
+    QObject::connect(_actionAddFolder, SIGNAL(triggered(bool)), SLOT(slotAddFolder()));
+    _actionQuit = new QAction(tr("Quit"), this);
+    QObject::connect(_actionQuit, SIGNAL(triggered(bool)), SLOT(quit()));
+}
+
+void Application::setupSystemTray()
+{
+    _tray = new QSystemTrayIcon(this);
+    _tray->setIcon(QIcon(FOLDER_ICON));
+    _tray->show();
+}
+
+void Application::setupContextMenu()
+{
+    QMenu *contextMenu = new QMenu();
+    contextMenu->addAction(_actionAddFolder);
+    contextMenu->addAction(_folder->action());
+    contextMenu->addSeparator();
+    contextMenu->addAction(_actionQuit);
+    _tray->setContextMenu(contextMenu);
+}
+
+void Application::slotAddFolder()
+{
+    qDebug() << "add a folder here...";
+}
+
+
+} // namespace Mirall
+
+#include "application.moc"

+ 40 - 0
src/mirall/application.h

@@ -0,0 +1,40 @@
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+#include <QApplication>
+
+class QAction;
+class QSystemTrayIcon;
+
+namespace Mirall {
+
+class Folder;
+
+class Application : public QApplication
+{
+    Q_OBJECT
+public:
+    explicit Application(int argc, char **argv);
+    ~Application();
+signals:
+
+protected slots:
+
+    void slotAddFolder();
+
+protected:
+
+    void setupActions();
+    void setupSystemTray();
+    void setupContextMenu();
+
+private:
+    Folder *_folder;
+    QSystemTrayIcon *_tray;
+    QAction *_actionQuit;
+    QAction *_actionAddFolder;
+};
+
+} // namespace Mirall
+
+#endif // APPLICATION_H

+ 9 - 0
src/mirall/constants.h

@@ -0,0 +1,9 @@
+
+#ifndef MIRALL_CONSTANTS_H
+#define MIRALL_CONSTANTS_H
+
+#define FOLDER_ICON "/usr/share/icons/oxygen/48x48/places/folder-favorites.png"
+#define FOLDER_SYNC_ICON = "/usr/share/icons/oxygen/48x48/actions/folder-sync.png"
+#define FOLDER_SYNC_ERROR = "/usr/share/icons/oxygen/48x48/places/folder-important.png"
+
+#endif

+ 48 - 0
src/mirall/folder.cpp

@@ -0,0 +1,48 @@
+#include <QAction>
+#include <QDebug>
+#include <QDesktopServices>
+#include <QIcon>
+#include <QMutexLocker>
+#include <QUrl>
+
+#include "mirall/constants.h"
+#include "mirall/folder.h"
+#include "mirall/folderwatcher.h"
+
+namespace Mirall {
+
+Folder::Folder(const QString &path, QObject *parent)
+    : QObject(parent),
+      _path(path)
+{
+    _action = new QAction(QIcon(FOLDER_ICON), path, this);
+    QObject::connect(_action, SIGNAL(triggered(bool)), SLOT(slotOpenFolder()));
+
+    _watcher = new Mirall::FolderWatcher(path, this);
+    QObject::connect(_watcher, SIGNAL(folderChanged(const QString &)),
+                     SLOT(slotChanged(const QString &)));
+}
+
+QAction * Folder::action() const
+{
+    return _action;
+}
+
+Folder::~Folder()
+{
+}
+
+void Folder::slotChanged(const QString &path)
+{
+    //qDebug() << "path " << path << " changed";
+}
+
+void Folder::slotOpenFolder()
+{
+    QDesktopServices::openUrl(QUrl(_path));
+}
+
+
+} // namespace Mirall
+
+#include "folder.moc"

+ 46 - 0
src/mirall/folder.h

@@ -0,0 +1,46 @@
+#ifndef MIRALL_FOLDER_H
+#define MIRALL_FOLDER_H
+
+#include <QObject>
+#include <QString>
+
+class QAction;
+
+namespace Mirall {
+
+class FolderWatcher;
+
+class Folder : public QObject
+{
+    Q_OBJECT
+
+public:
+    Folder(const QString &path, QObject *parent = 0L);
+    virtual ~Folder();
+
+    QAction *action() const;
+
+    /**
+     * starts a sync operation
+     * requests are serialized
+     */
+    virtual void startSync() = 0;
+
+signals:
+    void syncStarted();
+    void syncFinished();
+
+protected:
+
+private:
+    QString _path;
+    FolderWatcher *_watcher;
+    QAction *_action;
+private slots:
+    void slotChanged(const QString &path);
+    void slotOpenFolder();
+};
+
+}
+
+#endif

+ 105 - 0
src/mirall/folderwatcher.cpp

@@ -0,0 +1,105 @@
+
+#include <QFileInfo>
+#include <QFileSystemWatcher>
+#include <QFlags>
+#include <QDebug>
+#include <QDir>
+#include <QMutexLocker>
+#include <QStringList>
+
+#include "mirall/folderwatcher.h"
+
+namespace Mirall {
+
+enum SubFolderListOption {
+    SubFolderNoOptions = 0x0,
+    SubFolderRecursive = 0x1,
+};
+Q_DECLARE_FLAGS(SubFolderListOptions, SubFolderListOption)
+Q_DECLARE_OPERATORS_FOR_FLAGS(SubFolderListOptions)
+
+// Forgive me using a bool as a flag
+static QStringList subFoldersList(QString folder,
+                                  SubFolderListOptions options = SubFolderNoOptions )
+{
+    QDir dir(folder);
+    dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
+
+    QFileInfoList list = dir.entryInfoList();
+    QStringList dirList;
+
+    for (int i = 0; i < list.size(); ++i) {
+        QFileInfo fileInfo = list.at(i);
+        dirList << fileInfo.absoluteFilePath();
+        if (options & SubFolderRecursive )
+            dirList << subFoldersList(fileInfo.absoluteFilePath(), options);
+    }
+    return dirList;
+}
+
+FolderWatcher::FolderWatcher(const QString &path, QObject *parent)
+    : QObject(parent)
+{
+    _watcher = new QFileSystemWatcher(this);
+
+    // watch the path and all subdirectories
+    {
+        QMutexLocker locker(&_mutex);
+
+        QStringList subfolders(subFoldersList(path, SubFolderRecursive));
+        qDebug() << "adding watchers for " << subfolders;
+
+        QStringListIterator subfoldersIt(subfolders);
+        while (subfoldersIt.hasNext()) {
+            _watcher->addPath(subfoldersIt.next());
+        }
+
+    }
+    QObject::connect(_watcher, SIGNAL(directoryChanged(const QString &)),
+                     SLOT(slotDirectoryChanged(const QString &)));
+}
+
+FolderWatcher::~FolderWatcher()
+{
+
+}
+
+void FolderWatcher::slotDirectoryChanged(const QString &path)
+{
+    QMutexLocker locker(&_mutex);
+
+    qDebug() << "changed: " << path;
+
+    qDebug() << "updating subdirectories";
+
+    QStringList watchedFolders(_watcher->directories());
+    QStringListIterator watchedFoldersIt(watchedFolders);
+
+    while (watchedFoldersIt.hasNext()) {
+        QDir folder (watchedFoldersIt.next());
+        if (!folder.exists()){
+            qDebug() << "Removing " << folder.path();
+            _watcher->removePath(folder.path());
+        }
+    }
+
+    QStringListIterator subfoldersIt(subFoldersList(path, SubFolderRecursive));
+    while (subfoldersIt.hasNext()) {
+        QDir folder (subfoldersIt.next());
+        if (folder.exists() && !watchedFolders.contains(folder.path())) {
+            qDebug() << "Adding " << folder.path();
+            _watcher->addPath(folder.path());
+        }
+
+        // Look if some of the subdirectories disappeared
+
+
+    }
+
+
+    emit folderChanged(path);
+}
+
+}
+
+#include "folderwatcher.moc"

+ 30 - 0
src/mirall/folderwatcher.h

@@ -0,0 +1,30 @@
+
+#ifndef MIRALL_FOLDERWATCHER_H
+#define MIRALL_FOLDERWATCHER_H
+
+#include <QObject>
+#include <QString>
+#include <QMutex>
+
+class QFileSystemWatcher;
+
+namespace Mirall {
+
+class FolderWatcher : public QObject
+{
+Q_OBJECT
+public:
+    FolderWatcher(const QString &path, QObject *parent = 0L);
+    ~FolderWatcher();
+signals:
+    void folderChanged(const QString &path);
+protected slots:
+    void slotDirectoryChanged(const QString &path);
+private:
+    QFileSystemWatcher *_watcher;
+    QMutex _mutex;
+};
+
+}
+
+#endif

+ 24 - 0
src/mirall/gitfolder.cpp

@@ -0,0 +1,24 @@
+#include <QMutexLocker>
+#include "mirall/gitfolder.h"
+
+namespace Mirall {
+
+GitFolder::GitFolder(const QString &path, QObject *parent)
+    : Folder(path, parent)
+{
+}
+
+GitFolder::~GitFolder()
+{
+}
+
+void GitFolder::startSync()
+{
+    QMutexLocker locker(&_syncMutex);
+    emit syncStarted();
+    emit syncFinished();
+}
+
+} // ns
+
+#include "gitfolder.moc"

+ 22 - 0
src/mirall/gitfolder.h

@@ -0,0 +1,22 @@
+#ifndef MIRALL_GITFOLDER_H
+#define MIRALL_GITFOLDER_H
+
+#include <QMutex>
+#include "mirall/folder.h"
+
+namespace Mirall {
+
+class GitFolder : public Folder
+{
+public:
+    GitFolder(const QString &path, QObject *parent = 0L);
+    virtual ~GitFolder();
+
+    virtual void startSync();
+private:
+    QMutex _syncMutex;
+};
+
+}
+
+#endif