Browse Source

Added git repo and repos models are added

Alexey Edelev 7 years ago
parent
commit
ece4dcc362
9 changed files with 203 additions and 48 deletions
  1. 4 2
      NiceGit.pro
  2. 9 17
      githandler.cpp
  3. 7 15
      githandler.h
  4. 23 9
      gitrepository.cpp
  5. 14 5
      gitrepository.h
  6. 5 0
      main.cpp
  7. 12 0
      qml/MainView.qml
  8. 92 0
      repositorymodel.cpp
  9. 37 0
      repositorymodel.h

+ 4 - 2
NiceGit.pro

@@ -7,11 +7,13 @@ LIBS += -lgit2
 SOURCES += \
     main.cpp \
     githandler.cpp \
-    gitrepository.cpp
+    gitrepository.cpp \
+    repositorymodel.cpp
 
 HEADERS += \
     githandler.h \
-    gitrepository.h
+    gitrepository.h \
+    repositorymodel.h
 
 DISTFILES += \
     qml/MainView.qml

+ 9 - 17
githandler.cpp

@@ -2,20 +2,22 @@
 
 #include <QDebug>
 #include <QUrl>
+#include <qqml.h>
+
+#include <gitrepository.h>
 
 extern "C" {
 #include <git2.h>
 }
 
 GitHandler::GitHandler() : QObject()
-    ,_repo(nullptr)
+  ,m_repositories(new RepositoryModel(this))
 {
     git_libgit2_init();
 }
 
 GitHandler::~GitHandler()
 {
-    close();
     git_libgit2_shutdown();
 }
 
@@ -28,29 +30,19 @@ void GitHandler::open(const QUrl &url)
 
 void GitHandler::open(const QString &path)
 {
-    close();
-
     git_buf root = {0,0,0};
     if(git_repository_discover(&root, path.toUtf8().data(), 0, NULL) != 0) {
         qDebug() << lastError();
         return;
     }
 
-    QString str = QString::fromUtf8(root.ptr, root.size);
-
-    if(git_repository_open(&_repo, str.toUtf8().data()) != 0) {
-        qDebug() << "Cannot open repository";
-        qDebug() << "Error:" << lastError();
-        close();
+    GitRepository* repo = new GitRepository(QString::fromUtf8(root.ptr, root.size));
+    if(!repo->isValid()) {
+        qDebug() << lastError();
+        return;
     }
-}
 
-void GitHandler::close()
-{
-    if(_repo) {
-        git_repository_free(_repo);
-    }
-    _repo = nullptr;
+    m_repositories->addRepository(repo);
 }
 
 QString GitHandler::lastError() const

+ 7 - 15
githandler.h

@@ -3,42 +3,34 @@
 
 #include <QObject>
 
-#include <gitrepository.h>
+#include <repositorymodel.h>
 
 class GitHandler : public QObject
 {
     Q_OBJECT
-    Q_PROPERTY(GitRepository* repo READ repo WRITE setRepo NOTIFY repoChanged)
+    Q_PROPERTY(RepositoryModel* repositories READ repositories NOTIFY repositoriesChanged)
 
 public:
     GitHandler();
     virtual ~GitHandler();
     Q_INVOKABLE void open(const QString &path);
     Q_INVOKABLE void open(const QUrl &url);
-    Q_INVOKABLE void close();
 
-    GitRepository* repo() const
+    RepositoryModel* repositories() const
     {
-        return m_repo;
+        return m_repositories;
     }
 
 public slots:
-    void setRepo(GitRepository* repo)
-    {
-        if (m_repo == repo)
-            return;
-
-        m_repo = repo;
-        emit repoChanged(repo);
-    }
 
 signals:
-    void repoChanged(GitRepository* repo);
+    void repositoriesChanged(RepositoryModel* repositories);
 
 protected:
     QString lastError() const;
+
 private:
-    GitRepository* m_repo;
+    RepositoryModel* m_repositories;
 };
 
 #endif // GITHANDLER_H

+ 23 - 9
gitrepository.cpp

@@ -1,22 +1,36 @@
 #include "gitrepository.h"
 
-GitRepository::GitRepository() : QObject()
-  ,m_repo(nullptr)
-{
+#include <QDebug>
+#include <QFileInfo>
+#include <QDir>
 
-}
+#include <git2.h>
 
-GitRepository~GitRepository()
+GitRepository::GitRepository(const QString& root) : QObject()
+  ,m_repo(nullptr)
 {
-
+    if(git_repository_open(&m_repo, root.toUtf8().data()) != 0) {
+        qDebug() << "Cannot open repository";
+        close();
+        return;
+    }
+
+    QFileInfo info(root);
+    m_root = root;
+    m_name = info.dirName();
+    m_path = info.filePath();
+    qDebug() << "New repo:" << m_name << m_root << m_path;
 }
 
-void GitRepository::open(const QString &path)
+GitRepository::~GitRepository()
 {
-
+    close();
 }
 
 void GitRepository::close()
 {
-
+    if(m_repo) {
+        git_repository_free(m_repo);
+    }
+    m_repo = nullptr;
 }

+ 14 - 5
gitrepository.h

@@ -14,15 +14,12 @@ class GitRepository : public QObject
 {
     Q_PROPERTY(QString root READ root WRITE setRoot NOTIFY rootChanged)
     Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+    Q_PROPERTY(QString path READ path NOTIFY rootChanged)
 
 public:
-    GitRepository();
+    GitRepository(const QString &root);
     ~GitRepository();
 
-    Q_INVOKABLE void open(const QString &path);
-    Q_INVOKABLE void open(const QUrl &url);
-    Q_INVOKABLE void close();
-
     QString root() const {
         return m_root;
     }
@@ -31,6 +28,15 @@ public:
         return m_name;
     }
 
+    QString path() const
+    {
+        return m_path;
+    }
+
+    bool isValid() const {
+        return m_repo != nullptr;
+    }
+
 public slots:
     void setRoot(QString root) {
         if (m_root == root)
@@ -53,9 +59,12 @@ signals:
     void nameChanged(QString name);
 
 private:
+    void close();
+
     QString m_root;
     QString m_name;
     git_repository* m_repo;
+    QString m_path;
 };
 
 #endif // GITREPOSITORY_H

+ 5 - 0
main.cpp

@@ -4,6 +4,8 @@
 #include <QQmlContext>
 
 #include <githandler.h>
+#include <gitrepository.h>
+#include <repositorymodel.h>
 
 #include <QDebug>
 
@@ -14,6 +16,9 @@ int main(int argc, char *argv[])
     QQuickView view;
 
     qmlRegisterUncreatableType<GitHandler>("org.semlanik.nicegit", 1, 0, "GitHandler", "Global for qml");
+    qmlRegisterUncreatableType<GitRepository>("org.semlanik.nicegit", 1, 0, "GitRepository", "Owned only by GitHandler");
+    qmlRegisterUncreatableType<RepositoryModel>("org.semlanik.nicegit", 1, 0, "RepositoryModel", "Owned only by GitHandler");
+
     GitHandler handler;
     view.rootContext()->setContextProperty("_handler", &handler);
     view.setSource(QUrl("qrc:/qml/MainView.qml"));

+ 12 - 0
qml/MainView.qml

@@ -4,6 +4,7 @@ import QtQuick.Dialogs 1.2
 
 Item {
     Row {
+        id: selector
         Text {
             text: "Active repository" + repoOpenDialog.fileUrl
         }
@@ -13,6 +14,17 @@ Item {
         }
     }
 
+    Column {
+        anchors.top: selector.bottom
+        Repeater {
+            model: _handler.repositories
+
+            Text {
+                text: model.repoName
+            }
+        }
+    }
+
     FileDialog {
         id: repoOpenDialog
         folder: "."

+ 92 - 0
repositorymodel.cpp

@@ -0,0 +1,92 @@
+#include "repositorymodel.h"
+#include <gitrepository.h>
+
+#include <QDebug>
+
+QHash<int, QByteArray> RepositoryModel::m_roles;
+
+RepositoryModel::RepositoryModel(QObject* parent) : QAbstractListModel(parent)
+{
+    if(m_roles.isEmpty()) {
+        m_roles[RepoName] = "repoName";
+        m_roles[RepoRoot] = "repoRoot";
+        m_roles[RepoBranches] = "repoBranches";
+    }
+}
+
+RepositoryModel::~RepositoryModel()
+{
+    foreach (QPointer<GitRepository> repo, m_repositories) {
+        delete repo.data();
+    }
+    m_repositories.clear();
+}
+
+bool RepositoryModel::addRepository(GitRepository* repo)
+{
+    if(repo == nullptr)
+    {
+        qDebug() << "Repo is null";
+        return false;
+    }
+
+    if(m_repositories.contains(repo->root())) {
+        qDebug() << "Repository" << repo->root() << "already exists";
+        return false;
+    }
+    beginInsertRows(QModelIndex(),0,0);
+    m_repositories.insert(repo->root(), QPointer<GitRepository>(repo));
+    endInsertRows();
+    return true;
+}
+
+void RepositoryModel::removeRepository(GitRepository* repo)
+{
+    if(repo == nullptr) {
+        return;
+    }
+
+    if(m_repositories.contains(repo->root())) {
+        beginRemoveRows(QModelIndex(), m_repositories.values().indexOf(repo), m_repositories.values().indexOf(repo));
+        m_repositories.remove(repo->root());
+        endRemoveRows();
+    }
+}
+
+void RepositoryModel::removeRepository(const QString& root)
+{
+    m_repositories.remove(root);
+}
+
+QVariant RepositoryModel::data(const QModelIndex &index, int role) const
+{
+    int row = index.row();
+
+    if(row < 0 || row >= m_repositories.count()) {
+        return QVariant();
+    }
+
+    GitRepository* repo = m_repositories.values().at(row).data();
+
+    switch (role) {
+    case RepoName:
+        return QVariant(repo->name());
+    case RepoRoot:
+        return QVariant(repo->root());
+    default:
+        break;
+    }
+    return QVariant();
+}
+
+int RepositoryModel::rowCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent)
+    return m_repositories.count();
+}
+
+QHash<int, QByteArray> RepositoryModel::roleNames() const
+{
+    return m_roles;
+}
+

+ 37 - 0
repositorymodel.h

@@ -0,0 +1,37 @@
+#ifndef REPOSITORYMODEL_H
+#define REPOSITORYMODEL_H
+
+#include <QAbstractListModel>
+#include <QHash>
+#include <QString>
+#include <QPointer>
+
+class GitRepository;
+
+class RepositoryModel : public QAbstractListModel
+{
+    Q_OBJECT
+public:
+    enum Roles {
+        RepoName,
+        RepoRoot,
+        RepoBranches
+    };
+
+    RepositoryModel(QObject *parent = 0);
+    ~RepositoryModel();
+
+    bool addRepository(GitRepository* repo);
+    void removeRepository(GitRepository* repo);
+    void removeRepository(const QString& root);
+
+    QVariant data(const QModelIndex &index, int role) const;
+    int rowCount(const QModelIndex &parent) const;
+    QHash<int, QByteArray> roleNames() const;
+
+private:
+    QHash<QString, QPointer<GitRepository>> m_repositories;
+    static QHash<int, QByteArray> m_roles;
+};
+
+#endif // REPOSITORYMODEL_H