diff options
author | Friedemann Kleint <[email protected]> | 2009-01-07 12:58:31 +0100 |
---|---|---|
committer | Friedemann Kleint <[email protected]> | 2009-01-07 12:58:31 +0100 |
commit | 352cf143535605d7e5488b33e395ce82c8c413fb (patch) | |
tree | 916bf26ecdc482bc88990f82018a2b5ad7f194ea /src/plugins/git/branchmodel.cpp | |
parent | 800baec88b60760404a7534ca451fbda506910b5 (diff) |
Fixes: Add way to create a new local branch in the git plugin
Task: 205821
Details: Split up the branch model into remote branch base class and extended local branch class with <New Branch> row.
Diffstat (limited to 'src/plugins/git/branchmodel.cpp')
-rw-r--r-- | src/plugins/git/branchmodel.cpp | 192 |
1 files changed, 154 insertions, 38 deletions
diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index b02d58dbd04..bb8ccf19510 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -2,6 +2,8 @@ #include "gitclient.h" #include <QtCore/QDebug> +#include <QtCore/QRegExp> +#include <QtCore/QTimer> enum { debug = 0 }; @@ -10,7 +12,7 @@ namespace Git { // Parse a branch line: " *name sha description". Return true if it is // the current one -bool BranchModel::Branch::parse(const QString &lineIn, bool *isCurrent) +bool RemoteBranchModel::Branch::parse(const QString &lineIn, bool *isCurrent) { if (debug) qDebug() << Q_FUNC_INFO << lineIn; @@ -28,40 +30,41 @@ bool BranchModel::Branch::parse(const QString &lineIn, bool *isCurrent) return true; } -static inline Qt::ItemFlags typeToModelFlags(BranchModel::Type t) +// ------ RemoteBranchModel +RemoteBranchModel::RemoteBranchModel(GitClient *client, QObject *parent) : + QAbstractListModel(parent), + m_flags(Qt::ItemIsSelectable|Qt::ItemIsEnabled), + m_client(client) { - Qt::ItemFlags rc = Qt::ItemIsSelectable|Qt::ItemIsEnabled; - if (t == BranchModel::LocalBranches) - rc |= Qt::ItemIsUserCheckable; - return rc; } -// --- BranchModel -BranchModel::BranchModel(GitClient *client, Type type, QObject *parent) : - QAbstractListModel(parent), - m_type(type), - m_flags(typeToModelFlags(type)), - m_client(client), - m_currentBranch(-1) +bool RemoteBranchModel::refresh(const QString &workingDirectory, QString *errorMessage) { + int currentBranch; + return refreshBranches(workingDirectory, true, ¤tBranch, errorMessage); } -int BranchModel::currentBranch() const +QString RemoteBranchModel::branchName(int row) const { - return m_currentBranch; + return m_branches.at(row).name; } -QString BranchModel::branchName(int row) const +QString RemoteBranchModel::workingDirectory() const { - return m_branches.at(row).name; + return m_workingDirectory; } -int BranchModel::rowCount(const QModelIndex & /* parent */) const +int RemoteBranchModel::branchCount() const { return m_branches.size(); } -QVariant BranchModel::data(const QModelIndex &index, int role) const +int RemoteBranchModel::rowCount(const QModelIndex & /* parent */) const +{ + return branchCount(); +} + +QVariant RemoteBranchModel::data(const QModelIndex &index, int role) const { const int row = index.row(); switch (role) { @@ -72,36 +75,52 @@ QVariant BranchModel::data(const QModelIndex &index, int role) const m_branches.at(row).toolTip = toolTip(m_branches.at(row).currentSHA); return m_branches.at(row).toolTip; break; - case Qt::CheckStateRole: - if (m_type == RemoteBranches) - return QVariant(); - return row == m_currentBranch ? Qt::Checked : Qt::Unchecked; default: break; } return QVariant(); } -Qt::ItemFlags BranchModel::flags(const QModelIndex & /*index */) const +Qt::ItemFlags RemoteBranchModel::flags(const QModelIndex & /* index */) const { return m_flags; } -bool BranchModel::refresh(const QString &workingDirectory, QString *errorMessage) +QString RemoteBranchModel::toolTip(const QString &sha) const +{ + // Show the sha description excluding diff as toolTip + QString output; + QString errorMessage; + if (!m_client->synchronousShow(m_workingDirectory, sha, &output, &errorMessage)) + return errorMessage; + // Remove 'diff' output + const int diffPos = output.indexOf(QLatin1String("\ndiff --")); + if (diffPos != -1) + output.remove(diffPos, output.size() - diffPos); + return output; +} + +bool RemoteBranchModel::runGitBranchCommand(const QString &workingDirectory, const QStringList &additionalArgs, QString *output, QString *errorMessage) +{ + return m_client->synchronousBranchCmd(workingDirectory, additionalArgs, output, errorMessage); +} + +bool RemoteBranchModel::refreshBranches(const QString &workingDirectory, bool remoteBranches, + int *currentBranch, QString *errorMessage) { // Run branch command with verbose. QStringList branchArgs(QLatin1String("-v")); QString output; - if (m_type == RemoteBranches) + *currentBranch = -1; + if (remoteBranches) branchArgs.push_back(QLatin1String("-r")); - if (!m_client->synchronousBranchCmd(workingDirectory, branchArgs, &output, errorMessage)) + if (!runGitBranchCommand(workingDirectory, branchArgs, &output, errorMessage)) return false; if (debug) qDebug() << Q_FUNC_INFO << workingDirectory << output; // Parse output m_workingDirectory = workingDirectory; m_branches.clear(); - m_currentBranch = -1; const QStringList branches = output.split(QLatin1Char('\n')); const int branchCount = branches.size(); bool isCurrent; @@ -110,25 +129,122 @@ bool BranchModel::refresh(const QString &workingDirectory, QString *errorMessage if (newBranch.parse(branches.at(b), &isCurrent)) { m_branches.push_back(newBranch); if (isCurrent) - m_currentBranch = b; + *currentBranch = b; } } reset(); return true; } -QString BranchModel::toolTip(const QString &sha) const +int RemoteBranchModel::findBranchByName(const QString &name) const { - // Show the sha description excluding diff as toolTip + const int count = branchCount(); + for (int i = 0; i < count; i++) + if (branchName(i) == name) + return i; + return -1; +} + +// --- LocalBranchModel +LocalBranchModel::LocalBranchModel(GitClient *client, QObject *parent) : + RemoteBranchModel(client, parent), + m_typeHere(tr("<New branch>")), + m_typeHereToolTip(tr("Type to create a new branch")), + m_currentBranch(-1) +{ +} + +int LocalBranchModel::currentBranch() const +{ + return m_currentBranch; +} + +bool LocalBranchModel::isNewBranchRow(int row) const +{ + return row >= branchCount(); +} + +Qt::ItemFlags LocalBranchModel::flags(const QModelIndex & index) const +{ + if (isNewBranchRow(index)) + return Qt::ItemIsEditable|Qt::ItemIsSelectable|Qt::ItemIsEnabled| Qt::ItemIsUserCheckable; + return RemoteBranchModel::flags(index) | Qt::ItemIsUserCheckable; +} + +int LocalBranchModel::rowCount(const QModelIndex & /* parent */) const +{ + return branchCount() + 1; +} + +QVariant LocalBranchModel::data(const QModelIndex &index, int role) const +{ + if (isNewBranchRow(index)) { + switch (role) { + case Qt::DisplayRole: + return m_typeHere; + case Qt::ToolTipRole: + return m_typeHereToolTip; + case Qt::CheckStateRole: + return QVariant(false); + } + return QVariant(); + } + + if (role == Qt::CheckStateRole) + return index.row() == m_currentBranch ? Qt::Checked : Qt::Unchecked; + return RemoteBranchModel::data(index, role); +} + +bool LocalBranchModel::refresh(const QString &workingDirectory, QString *errorMessage) +{ + return refreshBranches(workingDirectory, false, &m_currentBranch, errorMessage); +} + +bool LocalBranchModel::checkNewBranchName(const QString &name) const +{ + // Syntax + const QRegExp pattern(QLatin1String("[a-zA-Z0-9-_]+")); + if (!pattern.exactMatch(name)) + return false; + // existing + if (findBranchByName(name) != -1) + return false; + return true; +} + +bool LocalBranchModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + // Verify + if (role != Qt::EditRole || index.row() < branchCount()) + return false; + const QString branchName = value.toString(); + const bool ok = checkNewBranchName(branchName); + if (debug) + qDebug() << Q_FUNC_INFO << branchName << ok; + if (!ok) + return false; + // Create QString output; QString errorMessage; - if (!m_client->synchronousShow(m_workingDirectory, sha, &output, &errorMessage)) - return errorMessage; - // Remove 'diff' output - const int diffPos = output.indexOf(QLatin1String("\ndiff --")); - if (diffPos != -1) - output.remove(diffPos, output.size() - diffPos); - return output; + if (!runGitBranchCommand(workingDirectory(), QStringList(branchName), &output, &errorMessage)) + return false; + m_newBranch = branchName; + // Start a delayed complete refresh and return true for now. + QTimer::singleShot(0, this, SLOT(slotNewBranchDelayedRefresh())); + return true; +} + +void LocalBranchModel::slotNewBranchDelayedRefresh() +{ + if (debug) + qDebug() << Q_FUNC_INFO; + + QString errorMessage; + if (!refresh(workingDirectory(), &errorMessage)) { + qWarning("%s", qPrintable(errorMessage)); + return; + } + emit newBranchCreated(m_newBranch); } } |