aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/git/branchmodel.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <[email protected]>2009-01-07 12:58:31 +0100
committerFriedemann Kleint <[email protected]>2009-01-07 12:58:31 +0100
commit352cf143535605d7e5488b33e395ce82c8c413fb (patch)
tree916bf26ecdc482bc88990f82018a2b5ad7f194ea /src/plugins/git/branchmodel.cpp
parent800baec88b60760404a7534ca451fbda506910b5 (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.cpp192
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, &currentBranch, 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);
}
}