From b7a3fc7ab81e745c247f1a12d8802b9d7aab48b6 Mon Sep 17 00:00:00 2001 From: Duncan Mac-Vicar P Date: Thu, 17 Feb 2011 00:21:45 +0100 Subject: [PATCH] first port to C++ --- .gitignore | 3 + CMakeLists.txt | 6 ++ src/CMakeLists.txt | 17 ++++++ src/main.cpp | 9 +++ src/mirall/application.cpp | 61 ++++++++++++++++++++ src/mirall/application.h | 40 +++++++++++++ src/mirall/constants.h | 9 +++ src/mirall/folder.cpp | 48 ++++++++++++++++ src/mirall/folder.h | 46 +++++++++++++++ src/mirall/folderwatcher.cpp | 105 +++++++++++++++++++++++++++++++++++ src/mirall/folderwatcher.h | 30 ++++++++++ src/mirall/gitfolder.cpp | 24 ++++++++ src/mirall/gitfolder.h | 22 ++++++++ 13 files changed, 420 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt create mode 100644 src/main.cpp create mode 100644 src/mirall/application.cpp create mode 100644 src/mirall/application.h create mode 100644 src/mirall/constants.h create mode 100644 src/mirall/folder.cpp create mode 100644 src/mirall/folder.h create mode 100644 src/mirall/folderwatcher.cpp create mode 100644 src/mirall/folderwatcher.h create mode 100644 src/mirall/gitfolder.cpp create mode 100644 src/mirall/gitfolder.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..72c5f7a5d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +*flymake* + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..d27173622 --- /dev/null +++ b/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) + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 000000000..749d33ceb --- /dev/null +++ b/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}) + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 000000000..c07e3647b --- /dev/null +++ b/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(); +} + diff --git a/src/mirall/application.cpp b/src/mirall/application.cpp new file mode 100644 index 000000000..d0c0fe476 --- /dev/null +++ b/src/mirall/application.cpp @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +#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" diff --git a/src/mirall/application.h b/src/mirall/application.h new file mode 100644 index 000000000..3d6588e8c --- /dev/null +++ b/src/mirall/application.h @@ -0,0 +1,40 @@ +#ifndef APPLICATION_H +#define APPLICATION_H + +#include + +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 diff --git a/src/mirall/constants.h b/src/mirall/constants.h new file mode 100644 index 000000000..31b919a54 --- /dev/null +++ b/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 diff --git a/src/mirall/folder.cpp b/src/mirall/folder.cpp new file mode 100644 index 000000000..11954da54 --- /dev/null +++ b/src/mirall/folder.cpp @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include + +#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" diff --git a/src/mirall/folder.h b/src/mirall/folder.h new file mode 100644 index 000000000..07e2e707d --- /dev/null +++ b/src/mirall/folder.h @@ -0,0 +1,46 @@ +#ifndef MIRALL_FOLDER_H +#define MIRALL_FOLDER_H + +#include +#include + +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 diff --git a/src/mirall/folderwatcher.cpp b/src/mirall/folderwatcher.cpp new file mode 100644 index 000000000..3bda5272a --- /dev/null +++ b/src/mirall/folderwatcher.cpp @@ -0,0 +1,105 @@ + +#include +#include +#include +#include +#include +#include +#include + +#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" diff --git a/src/mirall/folderwatcher.h b/src/mirall/folderwatcher.h new file mode 100644 index 000000000..ea0ec2cf2 --- /dev/null +++ b/src/mirall/folderwatcher.h @@ -0,0 +1,30 @@ + +#ifndef MIRALL_FOLDERWATCHER_H +#define MIRALL_FOLDERWATCHER_H + +#include +#include +#include + +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 diff --git a/src/mirall/gitfolder.cpp b/src/mirall/gitfolder.cpp new file mode 100644 index 000000000..a99f3582f --- /dev/null +++ b/src/mirall/gitfolder.cpp @@ -0,0 +1,24 @@ +#include +#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" diff --git a/src/mirall/gitfolder.h b/src/mirall/gitfolder.h new file mode 100644 index 000000000..ebbef313a --- /dev/null +++ b/src/mirall/gitfolder.h @@ -0,0 +1,22 @@ +#ifndef MIRALL_GITFOLDER_H +#define MIRALL_GITFOLDER_H + +#include +#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