forked from qt-creator/qt-creator
VCS: Introduce Base class for VCS plugins, use in git.
Fixes: - Cannot diff a file that does not belong to a project - Cannot commit when a temporary diff/log view is open due to the current file pointing to a temporary directory - git's project-related actions not passing the correct relative path. Implementation: - Centralize code to listen for Qt Creator's relevant state changes in VCSBasePlugin, dispatching the changes to the instances affected. (avoiding multiple invocations of searches/QFileInfo on current). - Do the same for the corelistener catching closing SubmitEditors. - Introduce VCSBasePluginState representing the relevant state (current file/project). - Call git with working directory set and relative arguments - Remove setEnabled/isEnabled() logic of IVersionControl - Pass toplevel from VCSManager to avoid duplicate searches.
This commit is contained in:
@@ -48,13 +48,6 @@ public:
|
||||
|
||||
virtual QString name() const = 0;
|
||||
|
||||
virtual bool isEnabled() const = 0;
|
||||
|
||||
/*!
|
||||
* Enable the VCS, that is, make its menu actions visible.
|
||||
*/
|
||||
virtual void setEnabled(bool enabled) = 0;
|
||||
|
||||
/*!
|
||||
* Returns whether files in this directory should be managed with this
|
||||
* version control.
|
||||
|
@@ -46,15 +46,18 @@ enum { debug = 0 };
|
||||
namespace Core {
|
||||
|
||||
typedef QList<IVersionControl *> VersionControlList;
|
||||
typedef QMap<QString, IVersionControl *> VersionControlCache;
|
||||
|
||||
static inline VersionControlList allVersionControls()
|
||||
{
|
||||
return ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>();
|
||||
}
|
||||
|
||||
// ---- VCSManagerPrivate
|
||||
// ---- VCSManagerPrivate:
|
||||
// Maintains a cache of top-level directory->version control.
|
||||
|
||||
struct VCSManagerPrivate {
|
||||
QMap<QString, IVersionControl *> m_cachedMatches;
|
||||
VersionControlCache m_cachedMatches;
|
||||
};
|
||||
|
||||
VCSManager::VCSManager(QObject *parent) :
|
||||
@@ -79,57 +82,48 @@ void VCSManager::extensionsInitialized()
|
||||
}
|
||||
}
|
||||
|
||||
void VCSManager::setVCSEnabled(const QString &directory)
|
||||
IVersionControl* VCSManager::findVersionControlForDirectory(const QString &directory,
|
||||
QString *topLevelDirectory)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << Q_FUNC_INFO << directory;
|
||||
IVersionControl* managingVCS = findVersionControlForDirectory(directory);
|
||||
const VersionControlList versionControls = allVersionControls();
|
||||
foreach (IVersionControl *versionControl, versionControls) {
|
||||
const bool newEnabled = versionControl == managingVCS;
|
||||
if (newEnabled != versionControl->isEnabled())
|
||||
versionControl->setEnabled(newEnabled);
|
||||
}
|
||||
}
|
||||
typedef VersionControlCache::const_iterator VersionControlCacheConstIterator;
|
||||
const VersionControlCacheConstIterator cacheEnd = m_d->m_cachedMatches.constEnd();
|
||||
|
||||
void VCSManager::setAllVCSEnabled()
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
const VersionControlList versionControls = allVersionControls();
|
||||
foreach (IVersionControl *versionControl, versionControls)
|
||||
if (!versionControl->isEnabled())
|
||||
versionControl->setEnabled(true);
|
||||
}
|
||||
if (topLevelDirectory)
|
||||
topLevelDirectory->clear();
|
||||
|
||||
IVersionControl* VCSManager::findVersionControlForDirectory(const QString &directory)
|
||||
{
|
||||
// first look into the cache, check the whole name
|
||||
|
||||
{
|
||||
const QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory);
|
||||
if (it != m_d->m_cachedMatches.constEnd())
|
||||
return it.value();
|
||||
// First check if the directory has an entry, meaning it is a top level
|
||||
const VersionControlCacheConstIterator fullPathIt = m_d->m_cachedMatches.constFind(directory);
|
||||
if (fullPathIt != cacheEnd) {
|
||||
if (topLevelDirectory)
|
||||
*topLevelDirectory = directory;
|
||||
return fullPathIt.value();
|
||||
}
|
||||
|
||||
// Split the path, starting from top, try to find the matching repository
|
||||
int pos = 0;
|
||||
const QChar slash = QLatin1Char('/');
|
||||
while (true) {
|
||||
int index = directory.indexOf(slash, pos);
|
||||
const int index = directory.indexOf(slash, pos);
|
||||
if (index == -1)
|
||||
break;
|
||||
const QString directoryPart = directory.left(index);
|
||||
QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directoryPart);
|
||||
if (it != m_d->m_cachedMatches.constEnd())
|
||||
const VersionControlCacheConstIterator it = m_d->m_cachedMatches.constFind(directoryPart);
|
||||
if (it != cacheEnd) {
|
||||
if (topLevelDirectory)
|
||||
*topLevelDirectory = it.key();
|
||||
return it.value();
|
||||
pos = index+1;
|
||||
}
|
||||
pos = index + 1;
|
||||
}
|
||||
|
||||
// ah nothing so ask the IVersionControls directly
|
||||
// Nothing: ask the IVersionControls directly, insert the toplevel into the cache.
|
||||
const VersionControlList versionControls = allVersionControls();
|
||||
foreach (IVersionControl * versionControl, versionControls) {
|
||||
if (versionControl->managesDirectory(directory)) {
|
||||
m_d->m_cachedMatches.insert(versionControl->findTopLevelForDirectory(directory), versionControl);
|
||||
const QString topLevel = versionControl->findTopLevelForDirectory(directory);
|
||||
m_d->m_cachedMatches.insert(topLevel, versionControl);
|
||||
if (topLevelDirectory)
|
||||
*topLevelDirectory = topLevel;
|
||||
return versionControl;
|
||||
}
|
||||
}
|
||||
@@ -152,4 +146,14 @@ bool VCSManager::showDeleteDialog(const QString &fileName)
|
||||
return vc->vcsDelete(fileName);
|
||||
}
|
||||
|
||||
CORE_EXPORT QDebug operator<<(QDebug in, const VCSManager &v)
|
||||
{
|
||||
QDebug nospace = in.nospace();
|
||||
const VersionControlCache::const_iterator cend = v.m_d->m_cachedMatches.constEnd();
|
||||
for (VersionControlCache::const_iterator it = v.m_d->m_cachedMatches.constBegin(); it != cend; ++it)
|
||||
nospace << "Directory: " << it.key() << ' ' << it.value()->name() << '\n';
|
||||
nospace << '\n';
|
||||
return in;
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
@@ -35,20 +35,26 @@
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDebug;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
struct VCSManagerPrivate;
|
||||
class IVersionControl;
|
||||
|
||||
// The VCSManager has only one notable function:
|
||||
// findVersionControlFor(), which returns the IVersionControl * for a given
|
||||
// filename. Note that the VCSManager assumes that if a IVersionControl *
|
||||
// manages a directory, then it also manages all the files and all the
|
||||
// subdirectories.
|
||||
//
|
||||
// It works by asking all IVersionControl * if they manage the file, and ask
|
||||
// for the topmost directory it manages. This information is cached and
|
||||
// VCSManager thus knows pretty fast which IVersionControl * is responsible.
|
||||
/* VCSManager:
|
||||
* 1) Provides functionality for finding the IVersionControl * for a given
|
||||
* filename (findVersionControlForDirectory). Note that the VCSManager assumes
|
||||
* that if a IVersionControl * manages a directory, then it also manages
|
||||
* all the files and all the subdirectories.
|
||||
* It works by asking all IVersionControl * if they manage the file, and ask
|
||||
* for the topmost directory it manages. This information is cached and
|
||||
* VCSManager thus knows pretty fast which IVersionControl * is responsible.
|
||||
* 2) Passes on the changes from the version controls caused by updating or
|
||||
* branching repositories and routes them to its signals (repositoryChanged,
|
||||
* filesChanged). */
|
||||
|
||||
class CORE_EXPORT VCSManager : public QObject
|
||||
{
|
||||
@@ -60,19 +66,16 @@ public:
|
||||
|
||||
void extensionsInitialized();
|
||||
|
||||
IVersionControl *findVersionControlForDirectory(const QString &directory);
|
||||
|
||||
// Enable the VCS managing a certain directory only. This should
|
||||
// be used by project manager classes.
|
||||
void setVCSEnabled(const QString &directory);
|
||||
// Enable all VCS.
|
||||
void setAllVCSEnabled();
|
||||
IVersionControl *findVersionControlForDirectory(const QString &directory,
|
||||
QString *topLevelDirectory = 0);
|
||||
|
||||
// Shows a confirmation dialog, whether the file should also be deleted
|
||||
// from revision control Calls sccDelete on the file. Returns false
|
||||
// if a failure occurs
|
||||
bool showDeleteDialog(const QString &fileName);
|
||||
|
||||
friend CORE_EXPORT QDebug operator<<(QDebug in, const VCSManager &);
|
||||
|
||||
signals:
|
||||
void repositoryChanged(const QString &repository);
|
||||
void filesChanged(const QStringList &files);
|
||||
@@ -81,6 +84,8 @@ private:
|
||||
VCSManagerPrivate *m_d;
|
||||
};
|
||||
|
||||
CORE_EXPORT QDebug operator<<(QDebug in, const VCSManager &);
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // VCSMANAGER_H
|
||||
|
@@ -44,19 +44,6 @@ QString CVSControl::name() const
|
||||
return QLatin1String("cvs");
|
||||
}
|
||||
|
||||
bool CVSControl::isEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void CVSControl::setEnabled(bool enabled)
|
||||
{
|
||||
if (m_enabled != enabled) {
|
||||
m_enabled = enabled;
|
||||
emit enabledChanged(m_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
bool CVSControl::supportsOperation(Operation operation) const
|
||||
{
|
||||
bool rc = true;
|
||||
|
@@ -45,9 +45,6 @@ public:
|
||||
explicit CVSControl(CVSPlugin *plugin);
|
||||
virtual QString name() const;
|
||||
|
||||
virtual bool isEnabled() const;
|
||||
virtual void setEnabled(bool enabled);
|
||||
|
||||
virtual bool managesDirectory(const QString &directory) const;
|
||||
virtual QString findTopLevelForDirectory(const QString &directory) const;
|
||||
|
||||
@@ -59,9 +56,6 @@ public:
|
||||
void emitRepositoryChanged(const QString &s);
|
||||
void emitFilesChanged(const QStringList &l);
|
||||
|
||||
signals:
|
||||
void enabledChanged(bool);
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
CVSPlugin *m_plugin;
|
||||
|
@@ -151,7 +151,7 @@ Core::IEditor* locateEditor(const char *property, const QString &entry)
|
||||
CVSPlugin *CVSPlugin::m_cvsPluginInstance = 0;
|
||||
|
||||
CVSPlugin::CVSPlugin() :
|
||||
m_versionControl(0),
|
||||
VCSBase::VCSBasePlugin(QLatin1String(CVS::Constants::CVSCOMMITEDITOR_KIND)),
|
||||
m_projectExplorer(0),
|
||||
m_addAction(0),
|
||||
m_deleteAction(0),
|
||||
@@ -168,6 +168,7 @@ CVSPlugin::CVSPlugin() :
|
||||
m_submitDiffAction(0),
|
||||
m_submitUndoAction(0),
|
||||
m_submitRedoAction(0),
|
||||
m_menuAction(0),
|
||||
m_submitActionTriggered(false)
|
||||
{
|
||||
}
|
||||
@@ -205,10 +206,8 @@ static inline Core::Command *createSeparator(QObject *parent,
|
||||
return ami->registerAction(tmpaction, id, globalcontext);
|
||||
}
|
||||
|
||||
bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
bool CVSPlugin::initialize(const QStringList & /*arguments */, QString *errorMessage)
|
||||
{
|
||||
Q_UNUSED(arguments);
|
||||
|
||||
typedef VCSBase::VCSSubmitEditorFactory<CVSSubmitEditor> CVSSubmitEditorFactory;
|
||||
typedef VCSBase::VCSEditorFactory<CVSEditor> CVSEditorFactory;
|
||||
using namespace Constants;
|
||||
@@ -216,21 +215,17 @@ bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
using namespace Core::Constants;
|
||||
using namespace ExtensionSystem;
|
||||
|
||||
VCSBase::VCSBasePlugin::initialize(new CVSControl(this));
|
||||
|
||||
m_cvsPluginInstance = this;
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
|
||||
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":/trolltech.cvs/CVS.mimetypes.xml"), errorMessage))
|
||||
return false;
|
||||
|
||||
|
||||
m_versionControl = new CVSControl(this);
|
||||
addAutoReleasedObject(m_versionControl);
|
||||
|
||||
if (QSettings *settings = core->settings())
|
||||
m_settings.fromSettings(settings);
|
||||
|
||||
addAutoReleasedObject(new CoreListener(this));
|
||||
|
||||
addAutoReleasedObject(new SettingsPage);
|
||||
|
||||
addAutoReleasedObject(new CVSSubmitEditorFactory(&submitParameters));
|
||||
@@ -250,10 +245,7 @@ bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
ami->createMenu(QLatin1String(CMD_ID_CVS_MENU));
|
||||
cvsMenu->menu()->setTitle(tr("&CVS"));
|
||||
toolsContainer->addMenu(cvsMenu);
|
||||
if (QAction *ma = cvsMenu->menu()->menuAction()) {
|
||||
ma->setEnabled(m_versionControl->isEnabled());
|
||||
connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
|
||||
}
|
||||
m_menuAction = cvsMenu->menu()->menuAction();
|
||||
|
||||
QList<int> globalcontext;
|
||||
globalcontext << core->uniqueIDManager()->uniqueIdentifier(C_GLOBAL);
|
||||
@@ -360,30 +352,21 @@ bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
|
||||
m_submitRedoAction = new QAction(tr("&Redo"), this);
|
||||
command = ami->registerAction(m_submitRedoAction, Core::Constants::REDO, cvscommitcontext);
|
||||
|
||||
connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext *)), this, SLOT(updateActions()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVSPlugin::extensionsInitialized()
|
||||
{
|
||||
m_projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||
if (m_projectExplorer) {
|
||||
connect(m_projectExplorer,
|
||||
SIGNAL(currentProjectChanged(ProjectExplorer::Project*)),
|
||||
m_cvsPluginInstance, SLOT(updateActions()));
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
bool CVSPlugin::editorAboutToClose(Core::IEditor *iEditor)
|
||||
bool CVSPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor)
|
||||
{
|
||||
if (!iEditor || !isCommitEditorOpen() || qstrcmp(Constants::CVSCOMMITEDITOR, iEditor->kind()))
|
||||
if (!isCommitEditorOpen())
|
||||
return true;
|
||||
|
||||
Core::IFile *fileIFace = iEditor->file();
|
||||
const CVSSubmitEditor *editor = qobject_cast<CVSSubmitEditor *>(iEditor);
|
||||
Core::IFile *fileIFace = submitEditor->file();
|
||||
const CVSSubmitEditor *editor = qobject_cast<CVSSubmitEditor *>(submitEditor);
|
||||
if (!fileIFace || !editor)
|
||||
return true;
|
||||
|
||||
@@ -488,8 +471,11 @@ CVSSubmitEditor *CVSPlugin::openCVSSubmitEditor(const QString &fileName)
|
||||
return submitEditor;
|
||||
}
|
||||
|
||||
void CVSPlugin::updateActions()
|
||||
void CVSPlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as)
|
||||
{
|
||||
if (!VCSBase::VCSBasePlugin::enableMenuAction(as, m_menuAction))
|
||||
return;
|
||||
|
||||
m_diffProjectAction->setEnabled(true);
|
||||
m_commitAllAction->setEnabled(true);
|
||||
m_statusAction->setEnabled(true);
|
||||
@@ -554,7 +540,7 @@ void CVSPlugin::revertCurrentFile()
|
||||
const CVSResponse revertResponse = runCVS(args, files, cvsShortTimeOut, true);
|
||||
if (revertResponse.result == CVSResponse::Ok) {
|
||||
fcb.setModifiedReload(true);
|
||||
m_versionControl->emitFilesChanged(files);
|
||||
cvsVersionControl()->emitFilesChanged(files);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -738,7 +724,7 @@ void CVSPlugin::updateProject()
|
||||
const CVSResponse response = runCVS(args, topLevels, cvsLongTimeOut, true);
|
||||
if (response.result == CVSResponse::Ok)
|
||||
foreach(const QString &topLevel, topLevels)
|
||||
m_versionControl->emitRepositoryChanged(topLevel);
|
||||
cvsVersionControl()->emitRepositoryChanged(topLevel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1193,6 +1179,11 @@ QString CVSPlugin::findTopLevelForDirectoryI(const QString &directory) const
|
||||
return QString();
|
||||
}
|
||||
|
||||
CVSControl *CVSPlugin::cvsVersionControl() const
|
||||
{
|
||||
return static_cast<CVSControl *>(versionControl());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Q_EXPORT_PLUGIN(CVS::Internal::CVSPlugin)
|
||||
|
@@ -33,8 +33,7 @@
|
||||
#include "cvssettings.h"
|
||||
#include "cvsutils.h"
|
||||
|
||||
#include <coreplugin/icorelistener.h>
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <vcsbase/vcsbaseplugin.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDir;
|
||||
@@ -55,6 +54,10 @@ namespace ProjectExplorer {
|
||||
class ProjectExplorerPlugin;
|
||||
}
|
||||
|
||||
namespace VCSBase {
|
||||
class VCSBaseSubmitEditor;
|
||||
}
|
||||
|
||||
namespace CVS {
|
||||
namespace Internal {
|
||||
|
||||
@@ -80,7 +83,7 @@ struct CVSResponse
|
||||
* the diff editor has an additional property specifying the
|
||||
* base directory for its interaction to work. */
|
||||
|
||||
class CVSPlugin : public ExtensionSystem::IPlugin
|
||||
class CVSPlugin : public VCSBase::VCSBasePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -90,7 +93,6 @@ public:
|
||||
|
||||
virtual bool initialize(const QStringList &arguments, QString *error_message);
|
||||
virtual void extensionsInitialized();
|
||||
virtual bool editorAboutToClose(Core::IEditor *editor);
|
||||
|
||||
void cvsDiff(const QStringList &files, QString diffname = QString());
|
||||
|
||||
@@ -108,7 +110,6 @@ public:
|
||||
static CVSPlugin *cvsPluginInstance();
|
||||
|
||||
private slots:
|
||||
void updateActions();
|
||||
void addCurrentFile();
|
||||
void deleteCurrentFile();
|
||||
void revertCurrentFile();
|
||||
@@ -124,6 +125,10 @@ private slots:
|
||||
void submitCurrentLog();
|
||||
void diffFiles(const QStringList &);
|
||||
|
||||
protected:
|
||||
virtual void updateActions(VCSBase::VCSBasePlugin::ActionState);
|
||||
virtual bool submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor);
|
||||
|
||||
private:
|
||||
bool isCommitEditorOpen() const;
|
||||
QString currentFileName() const;
|
||||
@@ -152,9 +157,9 @@ private:
|
||||
void startCommit(const QString &file);
|
||||
bool commit(const QString &messageFile, const QStringList &subVersionFileList);
|
||||
void cleanCommitMessageFile();
|
||||
inline CVSControl *cvsVersionControl() const;
|
||||
|
||||
CVSSettings m_settings;
|
||||
CVSControl *m_versionControl;
|
||||
QString m_commitMessageFileName;
|
||||
|
||||
ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer;
|
||||
@@ -175,32 +180,12 @@ private:
|
||||
QAction *m_submitDiffAction;
|
||||
QAction *m_submitUndoAction;
|
||||
QAction *m_submitRedoAction;
|
||||
QAction *m_menuAction;
|
||||
bool m_submitActionTriggered;
|
||||
|
||||
static CVSPlugin *m_cvsPluginInstance;
|
||||
};
|
||||
|
||||
// Just a proxy for CVSPlugin
|
||||
class CoreListener : public Core::ICoreListener
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CoreListener(CVSPlugin *plugin) : m_plugin(plugin) { }
|
||||
|
||||
// Start commit when submit editor closes
|
||||
bool editorAboutToClose(Core::IEditor *editor) {
|
||||
return m_plugin->editorAboutToClose(editor);
|
||||
}
|
||||
|
||||
// TODO: how to handle that ???
|
||||
bool coreAboutToClose() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CVSPlugin *m_plugin;
|
||||
};
|
||||
|
||||
} // namespace CVS
|
||||
} // namespace Internal
|
||||
|
||||
|
@@ -32,7 +32,8 @@
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
using namespace Git::Internal;
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
ChangeSelectionDialog::ChangeSelectionDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
@@ -42,6 +43,21 @@ ChangeSelectionDialog::ChangeSelectionDialog(QWidget *parent)
|
||||
setWindowTitle(tr("Select a Git commit"));
|
||||
}
|
||||
|
||||
QString ChangeSelectionDialog::change() const
|
||||
{
|
||||
return m_ui.changeNumberEdit->text();
|
||||
}
|
||||
|
||||
QString ChangeSelectionDialog::repository() const
|
||||
{
|
||||
return m_ui.repositoryEdit->text();
|
||||
}
|
||||
|
||||
void ChangeSelectionDialog::setRepository(const QString &s)
|
||||
{
|
||||
m_ui.repositoryEdit->setText(s);
|
||||
}
|
||||
|
||||
void ChangeSelectionDialog::selectWorkingDirectory()
|
||||
{
|
||||
static QString location = QString();
|
||||
@@ -67,3 +83,6 @@ void ChangeSelectionDialog::selectWorkingDirectory()
|
||||
tr("Selected directory is not a Git repository"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -37,21 +37,22 @@
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
class GitPlugin;
|
||||
|
||||
class ChangeSelectionDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ChangeSelectionDialog(QWidget *parent = 0);
|
||||
|
||||
QString change() const;
|
||||
|
||||
QString repository() const;
|
||||
void setRepository(const QString &s);
|
||||
|
||||
public slots:
|
||||
void selectWorkingDirectory();
|
||||
|
||||
private:
|
||||
friend class GitPlugin;
|
||||
Ui_ChangeSelectionDialog m_ui;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -147,19 +147,6 @@ QString GitClient::findRepositoryForDirectory(const QString &dir)
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Return source file or directory string depending on parameters
|
||||
// ('git diff XX' -> 'XX' , 'git diff XX file' -> 'XX/file').
|
||||
static QString source(const QString &workingDirectory, const QString &fileName)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return workingDirectory;
|
||||
QString rc = workingDirectory;
|
||||
if (!rc.isEmpty() && !rc.endsWith(QDir::separator()))
|
||||
rc += QDir::separator();
|
||||
rc += fileName;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Create an editor associated to VCS output of a source file/directory
|
||||
* (using the file's codec). Makes use of a dynamic property to find an
|
||||
* existing instance and to reuse it (in case, say, 'git diff foo' is
|
||||
@@ -253,8 +240,7 @@ void GitClient::diff(const QString &workingDirectory,
|
||||
|
||||
const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND);
|
||||
const QString title = tr("Git Diff %1").arg(fileName);
|
||||
const QString sourceFile = source(workingDirectory, fileName);
|
||||
|
||||
const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, fileName);
|
||||
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "originalFileName", sourceFile);
|
||||
executeGit(workingDirectory, arguments, editor);
|
||||
}
|
||||
@@ -267,10 +253,10 @@ void GitClient::status(const QString &workingDirectory)
|
||||
executeGit(workingDirectory, statusArgs, 0, true);
|
||||
}
|
||||
|
||||
void GitClient::log(const QString &workingDirectory, const QString &fileName)
|
||||
void GitClient::log(const QString &workingDirectory, const QStringList &fileNames)
|
||||
{
|
||||
if (Git::Constants::debug)
|
||||
qDebug() << "log" << workingDirectory << fileName;
|
||||
qDebug() << "log" << workingDirectory << fileNames;
|
||||
|
||||
QStringList arguments;
|
||||
arguments << QLatin1String("log") << QLatin1String(noColorOption);
|
||||
@@ -278,12 +264,14 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName)
|
||||
if (m_settings.logCount > 0)
|
||||
arguments << QLatin1String("-n") << QString::number(m_settings.logCount);
|
||||
|
||||
if (!fileName.isEmpty())
|
||||
arguments << fileName;
|
||||
if (!fileNames.isEmpty())
|
||||
arguments.append(fileNames);
|
||||
|
||||
const QString title = tr("Git Log %1").arg(fileName);
|
||||
const QString msgArg = fileNames.empty() ? workingDirectory :
|
||||
fileNames.join(QString(", "));
|
||||
const QString title = tr("Git Log %1").arg(msgArg);
|
||||
const QString kind = QLatin1String(Git::Constants::GIT_LOG_EDITOR_KIND);
|
||||
const QString sourceFile = source(workingDirectory, fileName);
|
||||
const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, fileNames);
|
||||
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, false, "logFileName", sourceFile);
|
||||
executeGit(workingDirectory, arguments, editor);
|
||||
}
|
||||
@@ -313,7 +301,7 @@ void GitClient::blame(const QString &workingDirectory, const QString &fileName,
|
||||
|
||||
const QString kind = QLatin1String(Git::Constants::GIT_BLAME_EDITOR_KIND);
|
||||
const QString title = tr("Git Blame %1").arg(fileName);
|
||||
const QString sourceFile = source(workingDirectory, fileName);
|
||||
const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, fileName);
|
||||
|
||||
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "blameFileName", sourceFile);
|
||||
executeGit(workingDirectory, arguments, editor, false, GitCommand::NoReport, lineNumber);
|
||||
@@ -912,7 +900,7 @@ void GitClient::revert(const QStringList &files)
|
||||
QString errorMessage;
|
||||
switch (revertI(files, &isDirectory, &errorMessage)) {
|
||||
case RevertOk:
|
||||
m_plugin->versionControl()->emitFilesChanged(files);
|
||||
m_plugin->gitVersionControl()->emitFilesChanged(files);
|
||||
break;
|
||||
case RevertCanceled:
|
||||
break;
|
||||
@@ -1020,7 +1008,7 @@ void GitClient::connectRepositoryChanged(const QString & repository, GitCommand
|
||||
if (!m_repositoryChangedSignalMapper) {
|
||||
m_repositoryChangedSignalMapper = new QSignalMapper(this);
|
||||
connect(m_repositoryChangedSignalMapper, SIGNAL(mapped(QString)),
|
||||
m_plugin->versionControl(), SIGNAL(repositoryChanged(QString)));
|
||||
m_plugin->gitVersionControl(), SIGNAL(repositoryChanged(QString)));
|
||||
}
|
||||
m_repositoryChangedSignalMapper->setMapping(cmd, repository);
|
||||
connect(cmd, SIGNAL(success()), m_repositoryChangedSignalMapper, SLOT(map()),
|
||||
|
@@ -79,7 +79,7 @@ public:
|
||||
const QStringList &unstagedFileNames, const QStringList &stagedFileNames= QStringList());
|
||||
|
||||
void status(const QString &workingDirectory);
|
||||
void log(const QString &workingDirectory, const QString &fileName);
|
||||
void log(const QString &workingDirectory, const QStringList &fileNames);
|
||||
void blame(const QString &workingDirectory, const QString &fileName, int lineNumber = -1);
|
||||
void showCommit(const QString &workingDirectory, const QString &commit);
|
||||
void checkout(const QString &workingDirectory, const QString &file);
|
||||
|
@@ -56,10 +56,6 @@
|
||||
#include <vcsbase/basevcssubmiteditorfactory.h>
|
||||
#include <vcsbase/vcsbaseoutputwindow.h>
|
||||
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFileInfo>
|
||||
@@ -105,23 +101,16 @@ static inline const VCSBase::VCSBaseEditorParameters *findType(int ie)
|
||||
using namespace Git;
|
||||
using namespace Git::Internal;
|
||||
|
||||
// CoreListener
|
||||
|
||||
bool CoreListener::editorAboutToClose(Core::IEditor *editor)
|
||||
{
|
||||
return m_plugin->editorAboutToClose(editor);
|
||||
}
|
||||
|
||||
// GitPlugin
|
||||
|
||||
GitPlugin *GitPlugin::m_instance = 0;
|
||||
|
||||
GitPlugin::GitPlugin() :
|
||||
VCSBase::VCSBasePlugin(QLatin1String(Git::Constants::GITSUBMITEDITOR_KIND)),
|
||||
m_core(0),
|
||||
m_diffAction(0),
|
||||
m_diffProjectAction(0),
|
||||
m_statusAction(0),
|
||||
m_statusProjectAction(0),
|
||||
m_statusRepositoryAction(0),
|
||||
m_logAction(0),
|
||||
m_blameAction(0),
|
||||
m_logProjectAction(0),
|
||||
@@ -141,8 +130,8 @@ GitPlugin::GitPlugin() :
|
||||
m_stashPopAction(0),
|
||||
m_stashListAction(0),
|
||||
m_branchListAction(0),
|
||||
m_menuAction(0),
|
||||
m_gitClient(0),
|
||||
m_versionControl(0),
|
||||
m_changeSelectionDialog(0),
|
||||
m_submitActionTriggered(false)
|
||||
{
|
||||
@@ -192,15 +181,17 @@ static Core::Command *createSeparator(Core::ActionManager *am,
|
||||
|
||||
bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
{
|
||||
typedef VCSBase::VCSEditorFactory<GitEditor> GitEditorFactory;
|
||||
typedef VCSBase::VCSSubmitEditorFactory<GitSubmitEditor> GitSubmitEditorFactory;
|
||||
|
||||
Q_UNUSED(arguments)
|
||||
Q_UNUSED(errorMessage)
|
||||
|
||||
typedef VCSBase::VCSEditorFactory<GitEditor> GitEditorFactory;
|
||||
typedef VCSBase::VCSSubmitEditorFactory<GitSubmitEditor> GitSubmitEditorFactory;
|
||||
|
||||
VCSBase::VCSBasePlugin::initialize(new GitVersionControl(m_gitClient));
|
||||
|
||||
m_core = Core::ICore::instance();
|
||||
m_gitClient = new GitClient(this);
|
||||
// Create the globalco6664324b12a3339d18251df1cd69a1da06d1e2dcntext list to register actions accordingly
|
||||
// Create the globalcontext list to register actions accordingly
|
||||
QList<int> globalcontext;
|
||||
globalcontext << m_core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_GLOBAL);
|
||||
|
||||
@@ -212,13 +203,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
for (int i = 0; i < editorCount; i++)
|
||||
addAutoReleasedObject(new GitEditorFactory(editorParameters + i, m_gitClient, describeSlot));
|
||||
|
||||
addAutoReleasedObject(new CoreListener(this));
|
||||
|
||||
addAutoReleasedObject(new GitSubmitEditorFactory(&submitParameters));
|
||||
|
||||
m_versionControl = new GitVersionControl(m_gitClient);
|
||||
addAutoReleasedObject(m_versionControl);
|
||||
|
||||
addAutoReleasedObject(new CloneWizard);
|
||||
addAutoReleasedObject(new Gitorious::Internal::GitoriousCloneWizard);
|
||||
|
||||
@@ -232,11 +217,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
actionManager->createMenu(QLatin1String("Git"));
|
||||
gitContainer->menu()->setTitle(tr("&Git"));
|
||||
toolsContainer->addMenu(gitContainer);
|
||||
if (QAction *ma = gitContainer->menu()->menuAction()) {
|
||||
ma->setEnabled(m_versionControl->isEnabled());
|
||||
connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
|
||||
}
|
||||
|
||||
m_menuAction = gitContainer->menu()->menuAction();
|
||||
Core::Command *command;
|
||||
|
||||
m_diffAction = new Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
@@ -246,13 +227,6 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
connect(m_diffAction, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_statusAction = new Utils::ParameterAction(tr("File Status"), tr("Status Related to \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_statusAction, "Git.Status", globalcontext);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+S")));
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_statusAction, SIGNAL(triggered()), this, SLOT(statusFile()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_logAction = new Utils::ParameterAction(tr("Log File"), tr("Log of \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_logAction, "Git.Log", globalcontext);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+L")));
|
||||
@@ -296,10 +270,9 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
connect(m_diffProjectAction, SIGNAL(triggered()), this, SLOT(diffCurrentProject()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_statusProjectAction = new Utils::ParameterAction(tr("Project Status"), tr("Status Project \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
command = actionManager->registerAction(m_statusProjectAction, "Git.StatusProject", globalcontext);
|
||||
command->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_statusProjectAction, SIGNAL(triggered()), this, SLOT(statusProject()));
|
||||
m_statusRepositoryAction = new QAction(tr("Repository Status"), this);
|
||||
command = actionManager->registerAction(m_statusRepositoryAction, "Git.StatusRepository", globalcontext);
|
||||
connect(m_statusRepositoryAction, SIGNAL(triggered()), this, SLOT(statusRepository()));
|
||||
gitContainer->addAction(command);
|
||||
|
||||
m_logProjectAction = new Utils::ParameterAction(tr("Log Project"), tr("Log Project \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
|
||||
@@ -386,12 +359,6 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
m_redoAction = new QAction(tr("&Redo"), this);
|
||||
command = actionManager->registerAction(m_redoAction, Core::Constants::REDO, submitContext);
|
||||
|
||||
// Ask for updates of our actions, in case context switches
|
||||
connect(m_core, SIGNAL(contextChanged(Core::IContext *)),
|
||||
this, SLOT(updateActions()));
|
||||
connect(m_core->fileManager(), SIGNAL(currentFileChanged(const QString &)),
|
||||
this, SLOT(updateActions()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -399,9 +366,9 @@ void GitPlugin::extensionsInitialized()
|
||||
{
|
||||
}
|
||||
|
||||
GitVersionControl *GitPlugin::versionControl() const
|
||||
GitVersionControl *GitPlugin::gitVersionControl() const
|
||||
{
|
||||
return m_versionControl;
|
||||
return static_cast<GitVersionControl *>(versionControl());
|
||||
}
|
||||
|
||||
void GitPlugin::submitEditorDiff(const QStringList &unstaged, const QStringList &staged)
|
||||
@@ -411,127 +378,83 @@ void GitPlugin::submitEditorDiff(const QStringList &unstaged, const QStringList
|
||||
|
||||
void GitPlugin::diffCurrentFile()
|
||||
{
|
||||
const QFileInfo fileInfo = currentFile();
|
||||
const QString fileName = fileInfo.fileName();
|
||||
const QString workingDirectory = fileInfo.absolutePath();
|
||||
m_gitClient->diff(workingDirectory, QStringList(), fileName);
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasFile(), return)
|
||||
m_gitClient->diff(state.currentFileTopLevel(), QStringList(), state.relativeCurrentFile());
|
||||
}
|
||||
|
||||
void GitPlugin::diffCurrentProject()
|
||||
{
|
||||
QString workingDirectory = getWorkingDirectory();
|
||||
if (workingDirectory.isEmpty())
|
||||
return;
|
||||
m_gitClient->diff(workingDirectory, QStringList(), QString());
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasProject(), return)
|
||||
m_gitClient->diff(state.currentProjectTopLevel(), QStringList(), state.relativeCurrentProject());
|
||||
}
|
||||
|
||||
QFileInfo GitPlugin::currentFile() const
|
||||
void GitPlugin::statusRepository()
|
||||
{
|
||||
QString fileName = m_core->fileManager()->currentFile();
|
||||
QFileInfo fileInfo(fileName);
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
QString GitPlugin::getWorkingDirectory()
|
||||
{
|
||||
QString workingDirectory;
|
||||
if (const ProjectExplorer::ProjectExplorerPlugin *p = ProjectExplorer::ProjectExplorerPlugin::instance())
|
||||
if (p && p->currentNode())
|
||||
workingDirectory = QFileInfo(p->currentNode()->path()).absolutePath();
|
||||
|
||||
if (Git::Constants::debug > 1)
|
||||
qDebug() << Q_FUNC_INFO << "Project" << workingDirectory;
|
||||
|
||||
if (workingDirectory.isEmpty())
|
||||
workingDirectory = QFileInfo(m_core->fileManager()->currentFile()).absolutePath();
|
||||
if (Git::Constants::debug > 1)
|
||||
qDebug() << Q_FUNC_INFO << "file" << workingDirectory;
|
||||
|
||||
if (workingDirectory.isEmpty()) {
|
||||
VCSBase::VCSBaseOutputWindow::instance()->appendError(tr("Could not find working directory"));
|
||||
return QString();
|
||||
}
|
||||
return workingDirectory;
|
||||
}
|
||||
|
||||
void GitPlugin::statusProject()
|
||||
{
|
||||
QString workingDirectory = getWorkingDirectory();
|
||||
if (workingDirectory.isEmpty())
|
||||
return;
|
||||
m_gitClient->status(workingDirectory);
|
||||
}
|
||||
|
||||
void GitPlugin::statusFile()
|
||||
{
|
||||
m_gitClient->status(currentFile().absolutePath());
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
m_gitClient->status(state.topLevel());
|
||||
}
|
||||
|
||||
void GitPlugin::logFile()
|
||||
{
|
||||
const QFileInfo fileInfo = currentFile();
|
||||
const QString fileName = fileInfo.fileName();
|
||||
const QString workingDirectory = fileInfo.absolutePath();
|
||||
m_gitClient->log(workingDirectory, fileName);
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasFile(), return)
|
||||
m_gitClient->log(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()));
|
||||
}
|
||||
|
||||
void GitPlugin::blameFile()
|
||||
{
|
||||
const QFileInfo fileInfo = currentFile();
|
||||
const QString fileName = fileInfo.fileName();
|
||||
const QString workingDirectory = fileInfo.absolutePath();
|
||||
|
||||
m_gitClient->blame(workingDirectory, fileName,
|
||||
VCSBase::VCSBaseEditor::lineNumberOfCurrentEditor(fileInfo.absoluteFilePath()));
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasFile(), return)
|
||||
const int lineNumber = VCSBase::VCSBaseEditor::lineNumberOfCurrentEditor(state.currentFile());
|
||||
m_gitClient->blame(state.currentFileTopLevel(), state.relativeCurrentFile(), lineNumber);
|
||||
}
|
||||
|
||||
void GitPlugin::logProject()
|
||||
{
|
||||
QString workingDirectory = getWorkingDirectory();
|
||||
if (workingDirectory.isEmpty())
|
||||
return;
|
||||
m_gitClient->log(workingDirectory, QString());
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasProject(), return)
|
||||
m_gitClient->log(state.currentProjectTopLevel(), state.relativeCurrentProject());
|
||||
}
|
||||
|
||||
void GitPlugin::undoFileChanges()
|
||||
{
|
||||
const QFileInfo fileInfo = currentFile();
|
||||
Core::FileChangeBlocker fcb(fileInfo.filePath());
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasFile(), return)
|
||||
Core::FileChangeBlocker fcb(state.currentFile());
|
||||
fcb.setModifiedReload(true);
|
||||
|
||||
m_gitClient->revert(QStringList(fileInfo.absoluteFilePath()));
|
||||
m_gitClient->revert(QStringList(state.currentFile()));
|
||||
}
|
||||
|
||||
void GitPlugin::undoProjectChanges()
|
||||
{
|
||||
const QString workingDirectory = getWorkingDirectory();
|
||||
if (workingDirectory.isEmpty())
|
||||
return;
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
const QString msg = tr("Would you like to revert all pending changes to the repository\n%1?").arg(state.topLevel());
|
||||
const QMessageBox::StandardButton answer
|
||||
= QMessageBox::question(m_core->mainWindow(),
|
||||
tr("Revert"),
|
||||
tr("Would you like to revert all pending changes to the project?"),
|
||||
tr("Revert"), msg,
|
||||
QMessageBox::Yes|QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
if (answer == QMessageBox::No)
|
||||
return;
|
||||
m_gitClient->hardReset(workingDirectory, QString());
|
||||
m_gitClient->hardReset(state.topLevel(), QString());
|
||||
}
|
||||
|
||||
void GitPlugin::stageFile()
|
||||
{
|
||||
const QFileInfo fileInfo = currentFile();
|
||||
const QString fileName = fileInfo.fileName();
|
||||
const QString workingDirectory = fileInfo.absolutePath();
|
||||
m_gitClient->addFile(workingDirectory, fileName);
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasFile(), return)
|
||||
m_gitClient->addFile(state.currentFileTopLevel(), state.relativeCurrentFile());
|
||||
}
|
||||
|
||||
void GitPlugin::unstageFile()
|
||||
{
|
||||
const QFileInfo fileInfo = currentFile();
|
||||
const QString fileName = fileInfo.fileName();
|
||||
const QString workingDirectory = fileInfo.absolutePath();
|
||||
m_gitClient->synchronousReset(workingDirectory, QStringList(fileName));
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasFile(), return)
|
||||
m_gitClient->synchronousReset(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()));
|
||||
}
|
||||
|
||||
void GitPlugin::startCommit()
|
||||
@@ -543,15 +466,12 @@ void GitPlugin::startCommit()
|
||||
return;
|
||||
}
|
||||
|
||||
// Find repository and get commit data
|
||||
const QFileInfo currentFileInfo = currentFile();
|
||||
if (!currentFileInfo.exists())
|
||||
return;
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
|
||||
const QString workingDirectory = currentFileInfo.absolutePath();
|
||||
QString errorMessage, commitTemplate;
|
||||
CommitData data;
|
||||
if (!m_gitClient->getCommitData(workingDirectory, &commitTemplate, &data, &errorMessage)) {
|
||||
if (!m_gitClient->getCommitData(state.topLevel(), &commitTemplate, &data, &errorMessage)) {
|
||||
VCSBase::VCSBaseOutputWindow::instance()->append(errorMessage);
|
||||
return;
|
||||
}
|
||||
@@ -606,13 +526,12 @@ void GitPlugin::submitCurrentLog()
|
||||
m_core->editorManager()->closeEditors(editors);
|
||||
}
|
||||
|
||||
bool GitPlugin::editorAboutToClose(Core::IEditor *iEditor)
|
||||
bool GitPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor)
|
||||
{
|
||||
// Closing a submit editor?
|
||||
if (!iEditor || !isCommitEditorOpen() || qstrcmp(iEditor->kind(), Constants::GITSUBMITEDITOR_KIND))
|
||||
return true;
|
||||
Core::IFile *fileIFace = iEditor->file();
|
||||
const GitSubmitEditor *editor = qobject_cast<GitSubmitEditor *>(iEditor);
|
||||
if (!isCommitEditorOpen())
|
||||
return false;
|
||||
Core::IFile *fileIFace = submitEditor->file();
|
||||
const GitSubmitEditor *editor = qobject_cast<GitSubmitEditor *>(submitEditor);
|
||||
if (!fileIFace || !editor)
|
||||
return true;
|
||||
// Submit editor closing. Make it write out the commit message
|
||||
@@ -668,15 +587,14 @@ bool GitPlugin::editorAboutToClose(Core::IEditor *iEditor)
|
||||
|
||||
void GitPlugin::pull()
|
||||
{
|
||||
const QString workingDirectory = getWorkingDirectory();
|
||||
if (workingDirectory.isEmpty())
|
||||
return;
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
|
||||
switch (m_gitClient->ensureStash(workingDirectory)) {
|
||||
switch (m_gitClient->ensureStash(state.topLevel())) {
|
||||
case GitClient::StashUnchanged:
|
||||
case GitClient::Stashed:
|
||||
case GitClient::NotStashed:
|
||||
m_gitClient->pull(workingDirectory);
|
||||
m_gitClient->pull(state.topLevel());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -684,34 +602,33 @@ void GitPlugin::pull()
|
||||
|
||||
void GitPlugin::push()
|
||||
{
|
||||
const QString workingDirectory = getWorkingDirectory();
|
||||
if (!workingDirectory.isEmpty())
|
||||
m_gitClient->push(workingDirectory);
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
m_gitClient->push(state.topLevel());
|
||||
}
|
||||
|
||||
void GitPlugin::stash()
|
||||
{
|
||||
const QString workingDirectory = getWorkingDirectory();
|
||||
if (!workingDirectory.isEmpty())
|
||||
m_gitClient->stash(workingDirectory);
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
m_gitClient->stash(state.topLevel());
|
||||
}
|
||||
|
||||
void GitPlugin::stashPop()
|
||||
{
|
||||
const QString workingDirectory = getWorkingDirectory();
|
||||
if (!workingDirectory.isEmpty())
|
||||
m_gitClient->stashPop(workingDirectory);
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
m_gitClient->stashPop(state.topLevel());
|
||||
}
|
||||
|
||||
void GitPlugin::branchList()
|
||||
{
|
||||
const QString workingDirectory = getWorkingDirectory();
|
||||
if (workingDirectory.isEmpty())
|
||||
return;
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
QString errorMessage;
|
||||
BranchDialog dialog(m_core->mainWindow());
|
||||
|
||||
if (!dialog.init(m_gitClient, workingDirectory, &errorMessage)) {
|
||||
if (!dialog.init(m_gitClient, state.topLevel(), &errorMessage)) {
|
||||
VCSBase::VCSBaseOutputWindow::instance()->appendError(errorMessage);
|
||||
return;
|
||||
}
|
||||
@@ -720,85 +637,67 @@ void GitPlugin::branchList()
|
||||
|
||||
void GitPlugin::stashList()
|
||||
{
|
||||
const QString workingDirectory = getWorkingDirectory();
|
||||
if (!workingDirectory.isEmpty())
|
||||
m_gitClient->stashList(workingDirectory);
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return)
|
||||
m_gitClient->stashList(state.topLevel());
|
||||
}
|
||||
|
||||
void GitPlugin::updateActions()
|
||||
void GitPlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as)
|
||||
{
|
||||
const QFileInfo current = currentFile();
|
||||
const QString fileName = current.fileName();
|
||||
const QString currentDirectory = getWorkingDirectory();
|
||||
const QString repository = m_gitClient->findRepositoryForFile(current.absoluteFilePath());
|
||||
// First check for file commands and if the current file is inside
|
||||
// a Git-repository
|
||||
if (!VCSBase::VCSBasePlugin::enableMenuAction(as, m_menuAction))
|
||||
return;
|
||||
|
||||
const QString fileName = currentState().currentFileName();
|
||||
m_diffAction->setParameter(fileName);
|
||||
m_statusAction->setParameter(fileName);
|
||||
m_logAction->setParameter(fileName);
|
||||
m_blameAction->setParameter(fileName);
|
||||
m_undoFileAction->setParameter(fileName);
|
||||
m_stageAction->setParameter(fileName);
|
||||
m_unstageAction->setParameter(fileName);
|
||||
|
||||
bool enabled = !fileName.isEmpty() && !repository.isEmpty();
|
||||
m_diffAction->setEnabled(enabled);
|
||||
m_statusAction->setEnabled(enabled);
|
||||
m_logAction->setEnabled(enabled);
|
||||
m_blameAction->setEnabled(enabled);
|
||||
m_undoFileAction->setEnabled(enabled);
|
||||
m_stageAction->setEnabled(enabled);
|
||||
m_unstageAction->setEnabled(enabled);
|
||||
bool fileEnabled = !fileName.isEmpty();
|
||||
m_diffAction->setEnabled(fileEnabled);
|
||||
m_logAction->setEnabled(fileEnabled);
|
||||
m_blameAction->setEnabled(fileEnabled);
|
||||
m_undoFileAction->setEnabled(fileEnabled);
|
||||
m_stageAction->setEnabled(fileEnabled);
|
||||
m_unstageAction->setEnabled(fileEnabled);
|
||||
|
||||
if (repository.isEmpty()) {
|
||||
// If the file is not in a repository, the corresponding project will
|
||||
// be neither and we can disable everything and return
|
||||
m_diffProjectAction->setEnabled(false);
|
||||
m_diffProjectAction->setParameter(repository);
|
||||
m_statusProjectAction->setParameter(repository);
|
||||
m_statusProjectAction->setEnabled(false);
|
||||
m_logProjectAction->setParameter(repository);
|
||||
m_logProjectAction->setEnabled(false);
|
||||
m_undoProjectAction->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
const QString projectName = currentState().currentProjectName();
|
||||
const bool projectEnabled = !projectName.isEmpty();
|
||||
m_diffProjectAction->setEnabled(projectEnabled);
|
||||
m_diffProjectAction->setParameter(projectName);
|
||||
m_logProjectAction->setEnabled(projectEnabled);
|
||||
m_logProjectAction->setParameter(projectName);
|
||||
m_undoProjectAction->setEnabled(projectEnabled);
|
||||
|
||||
// We only know the file is in some repository, we do not know
|
||||
// anything about any project so far.
|
||||
QString project;
|
||||
if (const ProjectExplorer::ProjectExplorerPlugin *p = ProjectExplorer::ProjectExplorerPlugin::instance()) {
|
||||
if (const ProjectExplorer::Node *node = p->currentNode())
|
||||
if (const ProjectExplorer::Node *projectNode = node->projectNode())
|
||||
project = QFileInfo(projectNode->path()).completeBaseName();
|
||||
}
|
||||
const bool repositoryEnabled = currentState().hasTopLevel();
|
||||
m_statusRepositoryAction->setEnabled(repositoryEnabled);
|
||||
m_branchListAction->setEnabled(repositoryEnabled);
|
||||
m_stashListAction->setEnabled(repositoryEnabled);
|
||||
m_stashPopAction->setEnabled(repositoryEnabled);
|
||||
|
||||
enabled = !project.isEmpty();
|
||||
m_diffProjectAction->setEnabled(enabled);
|
||||
m_diffProjectAction->setParameter(project);
|
||||
m_statusProjectAction->setEnabled(enabled);
|
||||
m_statusProjectAction->setParameter(project);
|
||||
m_logProjectAction->setEnabled(enabled);
|
||||
m_logProjectAction->setParameter(project);
|
||||
m_undoProjectAction->setEnabled(enabled);
|
||||
// Prompts for repo.
|
||||
m_showAction->setEnabled(true);
|
||||
}
|
||||
|
||||
void GitPlugin::showCommit()
|
||||
{
|
||||
const VCSBase::VCSBasePluginState state = currentState();
|
||||
|
||||
if (!m_changeSelectionDialog)
|
||||
m_changeSelectionDialog = new ChangeSelectionDialog();
|
||||
|
||||
const QFileInfo currentInfo = currentFile();
|
||||
QString repositoryLocation = m_gitClient->findRepositoryForFile(currentInfo.absoluteFilePath());
|
||||
if (!repositoryLocation.isEmpty())
|
||||
m_changeSelectionDialog->m_ui.repositoryEdit->setText(repositoryLocation);
|
||||
if (state.hasTopLevel())
|
||||
m_changeSelectionDialog->setRepository(state.topLevel());
|
||||
|
||||
if (m_changeSelectionDialog->exec() != QDialog::Accepted)
|
||||
return;
|
||||
const QString change = m_changeSelectionDialog->m_ui.changeNumberEdit->text();
|
||||
const QString change = m_changeSelectionDialog->change();
|
||||
if (change.isEmpty())
|
||||
return;
|
||||
|
||||
m_gitClient->show(m_changeSelectionDialog->m_ui.repositoryEdit->text(), change);
|
||||
m_gitClient->show(m_changeSelectionDialog->repository(), change);
|
||||
}
|
||||
|
||||
GitSettings GitPlugin::settings() const
|
||||
|
@@ -31,9 +31,9 @@
|
||||
#define GITPLUGIN_H
|
||||
|
||||
#include "settingspage.h"
|
||||
#include "vcsbase/vcsbaseplugin.h"
|
||||
|
||||
#include <coreplugin/editormanager/ieditorfactory.h>
|
||||
#include <coreplugin/icorelistener.h>
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
@@ -49,7 +49,6 @@ QT_END_NAMESPACE
|
||||
namespace Core {
|
||||
class IEditorFactory;
|
||||
class ICore;
|
||||
class IVersionControl;
|
||||
}
|
||||
namespace Utils {
|
||||
class ParameterAction;
|
||||
@@ -66,19 +65,7 @@ class GitSubmitEditor;
|
||||
struct CommitData;
|
||||
struct GitSettings;
|
||||
|
||||
// Just a proxy for GitPlugin
|
||||
class CoreListener : public Core::ICoreListener
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CoreListener(GitPlugin *plugin) : m_plugin(plugin) { }
|
||||
bool editorAboutToClose(Core::IEditor *editor);
|
||||
bool coreAboutToClose() { return true; }
|
||||
private:
|
||||
GitPlugin *m_plugin;
|
||||
};
|
||||
|
||||
class GitPlugin : public ExtensionSystem::IPlugin
|
||||
class GitPlugin : public VCSBase::VCSBasePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -91,25 +78,19 @@ public:
|
||||
virtual bool initialize(const QStringList &arguments, QString *error_message);
|
||||
virtual void extensionsInitialized();
|
||||
|
||||
QString getWorkingDirectory();
|
||||
GitVersionControl *gitVersionControl() const;
|
||||
|
||||
GitSettings settings() const;
|
||||
void setSettings(const GitSettings &s);
|
||||
|
||||
GitClient *gitClient() const;
|
||||
GitVersionControl *versionControl() const;
|
||||
|
||||
public slots:
|
||||
void updateActions();
|
||||
bool editorAboutToClose(Core::IEditor *editor);
|
||||
|
||||
private slots:
|
||||
void diffCurrentFile();
|
||||
void diffCurrentProject();
|
||||
void submitEditorDiff(const QStringList &unstaged, const QStringList &staged);
|
||||
void submitCurrentLog();
|
||||
void statusFile();
|
||||
void statusProject();
|
||||
void statusRepository();
|
||||
void logFile();
|
||||
void blameFile();
|
||||
void logProject();
|
||||
@@ -127,9 +108,12 @@ private slots:
|
||||
void pull();
|
||||
void push();
|
||||
|
||||
protected:
|
||||
virtual void updateActions(VCSBase::VCSBasePlugin::ActionState);
|
||||
virtual bool submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor);
|
||||
|
||||
private:
|
||||
bool isCommitEditorOpen() const;
|
||||
QFileInfo currentFile() const;
|
||||
Core::IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd);
|
||||
void cleanCommitMessageFile();
|
||||
|
||||
@@ -137,8 +121,7 @@ private:
|
||||
Core::ICore *m_core;
|
||||
Utils::ParameterAction *m_diffAction;
|
||||
Utils::ParameterAction *m_diffProjectAction;
|
||||
Utils::ParameterAction *m_statusAction;
|
||||
Utils::ParameterAction *m_statusProjectAction;
|
||||
QAction *m_statusRepositoryAction;
|
||||
Utils::ParameterAction *m_logAction;
|
||||
Utils::ParameterAction *m_blameAction;
|
||||
Utils::ParameterAction *m_logProjectAction;
|
||||
@@ -159,9 +142,9 @@ private:
|
||||
QAction *m_stashPopAction;
|
||||
QAction *m_stashListAction;
|
||||
QAction *m_branchListAction;
|
||||
QAction *m_menuAction;
|
||||
|
||||
GitClient *m_gitClient;
|
||||
GitVersionControl *m_versionControl;
|
||||
ChangeSelectionDialog *m_changeSelectionDialog;
|
||||
QString m_submitRepository;
|
||||
QStringList m_submitOrigCommitFiles;
|
||||
|
@@ -44,19 +44,6 @@ QString GitVersionControl::name() const
|
||||
return QLatin1String("git");
|
||||
}
|
||||
|
||||
bool GitVersionControl::isEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void GitVersionControl::setEnabled(bool enabled)
|
||||
{
|
||||
if (m_enabled != enabled) {
|
||||
m_enabled = enabled;
|
||||
emit enabledChanged(m_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
bool GitVersionControl::supportsOperation(Operation operation) const
|
||||
{
|
||||
bool rc = false;
|
||||
|
@@ -46,9 +46,6 @@ public:
|
||||
|
||||
virtual QString name() const;
|
||||
|
||||
virtual bool isEnabled() const;
|
||||
virtual void setEnabled(bool enabled);
|
||||
|
||||
bool managesDirectory(const QString &directory) const;
|
||||
virtual QString findTopLevelForDirectory(const QString &directory) const;
|
||||
|
||||
|
@@ -152,15 +152,6 @@ static const char * const CMD_ID_SEPARATOR1 = "Perforce.Separator1";
|
||||
static const char * const CMD_ID_SEPARATOR2 = "Perforce.Separator2";
|
||||
static const char * const CMD_ID_SEPARATOR3 = "Perforce.Separator3";
|
||||
|
||||
////
|
||||
// CoreListener
|
||||
////
|
||||
|
||||
bool CoreListener::editorAboutToClose(Core::IEditor *editor)
|
||||
{
|
||||
return m_plugin->editorAboutToClose(editor);
|
||||
}
|
||||
|
||||
////
|
||||
// PerforcePlugin
|
||||
////
|
||||
@@ -168,6 +159,7 @@ bool CoreListener::editorAboutToClose(Core::IEditor *editor)
|
||||
PerforcePlugin *PerforcePlugin::m_perforcePluginInstance = NULL;
|
||||
|
||||
PerforcePlugin::PerforcePlugin() :
|
||||
VCSBase::VCSBasePlugin(QLatin1String(Constants::PERFORCESUBMITEDITOR_KIND)),
|
||||
m_editAction(0),
|
||||
m_addAction(0),
|
||||
m_deleteAction(0),
|
||||
@@ -190,8 +182,7 @@ PerforcePlugin::PerforcePlugin() :
|
||||
m_submitActionTriggered(false),
|
||||
m_diffSelectedFiles(0),
|
||||
m_undoAction(0),
|
||||
m_redoAction(0),
|
||||
m_versionControl(0)
|
||||
m_redoAction(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -201,14 +192,13 @@ static const VCSBase::VCSBaseSubmitEditorParameters submitParameters = {
|
||||
Perforce::Constants::C_PERFORCESUBMITEDITOR
|
||||
};
|
||||
|
||||
bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
bool PerforcePlugin::initialize(const QStringList & /* arguments */, QString * errorMessage)
|
||||
{
|
||||
Q_UNUSED(arguments)
|
||||
Q_UNUSED(errorMessage)
|
||||
|
||||
typedef VCSBase::VCSEditorFactory<PerforceEditor> PerforceEditorFactory;
|
||||
typedef VCSBase::VCSSubmitEditorFactory<PerforceSubmitEditor> PerforceSubmitEditorFactory;
|
||||
|
||||
VCSBase::VCSBasePlugin::initialize(new PerforceVersionControl(this));
|
||||
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":/trolltech.perforce/Perforce.mimetypes.xml"), errorMessage))
|
||||
return false;
|
||||
@@ -227,11 +217,6 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
for (int i = 0; i < editorCount; i++)
|
||||
addAutoReleasedObject(new PerforceEditorFactory(editorParameters + i, this, describeSlot));
|
||||
|
||||
m_versionControl = new PerforceVersionControl(this);
|
||||
addAutoReleasedObject(m_versionControl);
|
||||
|
||||
addAutoReleasedObject(new CoreListener(this));
|
||||
|
||||
//register actions
|
||||
Core::ActionManager *am = Core::ICore::instance()->actionManager();
|
||||
|
||||
@@ -242,10 +227,7 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
am->createMenu(QLatin1String(CMD_ID_PERFORCE_MENU));
|
||||
mperforce->menu()->setTitle(tr("&Perforce"));
|
||||
mtools->addMenu(mperforce);
|
||||
if (QAction *ma = mperforce->menu()->menuAction()) {
|
||||
ma->setEnabled(m_versionControl->isEnabled());
|
||||
connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
|
||||
}
|
||||
m_menuAction = mperforce->menu()->menuAction();
|
||||
|
||||
QList<int> globalcontext;
|
||||
globalcontext << Core::Constants::C_GLOBAL_ID;
|
||||
@@ -397,24 +379,12 @@ bool PerforcePlugin::initialize(const QStringList &arguments, QString *errorMess
|
||||
m_redoAction = new QAction(tr("&Redo"), this);
|
||||
command = am->registerAction(m_redoAction, Core::Constants::REDO, perforcesubmitcontext);
|
||||
|
||||
connect(core, SIGNAL(contextChanged(Core::IContext *)),
|
||||
this, SLOT(updateActions()));
|
||||
|
||||
connect(core->fileManager(), SIGNAL(currentFileChanged(const QString &)),
|
||||
this, SLOT(updateActions()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PerforcePlugin::extensionsInitialized()
|
||||
{
|
||||
m_projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||
if (m_projectExplorer) {
|
||||
connect(m_projectExplorer,
|
||||
SIGNAL(currentProjectChanged(ProjectExplorer::Project*)),
|
||||
this, SLOT(updateActions()));
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void PerforcePlugin::openCurrentFile()
|
||||
@@ -455,7 +425,7 @@ void PerforcePlugin::revertCurrentFile()
|
||||
fcb.setModifiedReload(true);
|
||||
PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
|
||||
if (!result2.error)
|
||||
m_versionControl->emitFilesChanged(QStringList(fileName));
|
||||
perforceVersionControl()->emitFilesChanged(QStringList(fileName));
|
||||
}
|
||||
|
||||
void PerforcePlugin::diffCurrentFile()
|
||||
@@ -519,7 +489,7 @@ void PerforcePlugin::updateCheckout(const QStringList &dirs)
|
||||
const PerforceResponse resp = runP4Cmd(args, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
|
||||
if (!dirs.empty())
|
||||
foreach(const QString &dir, dirs)
|
||||
m_versionControl->emitRepositoryChanged(dir);
|
||||
perforceVersionControl()->emitRepositoryChanged(dir);
|
||||
}
|
||||
|
||||
void PerforcePlugin::printOpenedFileList()
|
||||
@@ -680,8 +650,11 @@ void PerforcePlugin::filelog(const QString &fileName)
|
||||
}
|
||||
}
|
||||
|
||||
void PerforcePlugin::updateActions()
|
||||
void PerforcePlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as)
|
||||
{
|
||||
if (!VCSBase::VCSBasePlugin::enableMenuAction(as, m_menuAction))
|
||||
return;
|
||||
|
||||
const QString fileName = currentFileName();
|
||||
const QString baseName = fileName.isEmpty() ? fileName : QFileInfo(fileName).fileName();
|
||||
|
||||
@@ -993,19 +966,16 @@ bool PerforcePlugin::isCommitEditorOpen() const
|
||||
return !m_commitMessageFileName.isEmpty();
|
||||
}
|
||||
|
||||
bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
|
||||
bool PerforcePlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor)
|
||||
{
|
||||
if (!editor || !isCommitEditorOpen())
|
||||
if (!isCommitEditorOpen())
|
||||
return true;
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
Core::IFile *fileIFace = editor->file();
|
||||
if (!fileIFace)
|
||||
Core::IFile *fileIFace = submitEditor->file();
|
||||
const PerforceSubmitEditor *perforceEditor = qobject_cast<PerforceSubmitEditor *>(submitEditor);
|
||||
if (!fileIFace || !perforceEditor)
|
||||
return true;
|
||||
const PerforceSubmitEditor *perforceEditor = qobject_cast<PerforceSubmitEditor *>(editor);
|
||||
if (!perforceEditor)
|
||||
return true;
|
||||
QFileInfo editorFile(fileIFace->fileName());
|
||||
QFileInfo changeFile(m_commitMessageFileName);
|
||||
const QFileInfo editorFile(fileIFace->fileName());
|
||||
const QFileInfo changeFile(m_commitMessageFileName);
|
||||
if (editorFile.absoluteFilePath() == changeFile.absoluteFilePath()) {
|
||||
// Prompt the user. Force a prompt unless submit was actually invoked (that
|
||||
// is, the editor was closed or shutdown).
|
||||
@@ -1025,9 +995,10 @@ bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
|
||||
m_settings.setPromptToSubmit(wantsPrompt);
|
||||
m_settings.toSettings(Core::ICore::instance()->settings());
|
||||
}
|
||||
core->fileManager()->blockFileChange(fileIFace);
|
||||
Core::FileManager *fileManager = Core::ICore::instance()->fileManager();
|
||||
fileManager->blockFileChange(fileIFace);
|
||||
fileIFace->save();
|
||||
core->fileManager()->unblockFileChange(fileIFace);
|
||||
fileManager->unblockFileChange(fileIFace);
|
||||
if (answer == VCSBase::VCSBaseSubmitEditor::SubmitConfirmed) {
|
||||
QFile commitMessageFile(m_commitMessageFileName);
|
||||
if (!commitMessageFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
|
||||
@@ -1071,7 +1042,7 @@ bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
|
||||
const QString output = QString::fromLocal8Bit(proc.readAll());
|
||||
VCSBase::VCSBaseOutputWindow::instance()->append(output);
|
||||
if (output.contains(QLatin1String("Out of date files must be resolved or reverted)"))) {
|
||||
QMessageBox::warning(editor->widget(), tr("Pending change"), tr("Could not submit the change, because your workspace was out of date. Created a pending submit instead."));
|
||||
QMessageBox::warning(submitEditor->widget(), tr("Pending change"), tr("Could not submit the change, because your workspace was out of date. Created a pending submit instead."));
|
||||
}
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
@@ -1219,5 +1190,10 @@ PerforcePlugin *PerforcePlugin::perforcePluginInstance()
|
||||
return m_perforcePluginInstance;
|
||||
}
|
||||
|
||||
PerforceVersionControl *PerforcePlugin::perforceVersionControl() const
|
||||
{
|
||||
return static_cast<PerforceVersionControl *>(versionControl());
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(PerforcePlugin)
|
||||
|
||||
|
@@ -34,8 +34,7 @@
|
||||
|
||||
#include <coreplugin/editormanager/ieditorfactory.h>
|
||||
#include <coreplugin/iversioncontrol.h>
|
||||
#include <coreplugin/icorelistener.h>
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <vcsbase/vcsbaseplugin.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
@@ -56,19 +55,6 @@ namespace Perforce {
|
||||
namespace Internal {
|
||||
|
||||
class PerforceVersionControl;
|
||||
class PerforcePlugin;
|
||||
|
||||
// Just a proxy for PerforcePlugin
|
||||
class CoreListener : public Core::ICoreListener
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CoreListener(PerforcePlugin *plugin) : m_plugin(plugin) { }
|
||||
bool editorAboutToClose(Core::IEditor *editor);
|
||||
bool coreAboutToClose() { return true; }
|
||||
private:
|
||||
PerforcePlugin *m_plugin;
|
||||
};
|
||||
|
||||
struct PerforceResponse
|
||||
{
|
||||
@@ -78,7 +64,7 @@ struct PerforceResponse
|
||||
QString message;
|
||||
};
|
||||
|
||||
class PerforcePlugin : public ExtensionSystem::IPlugin
|
||||
class PerforcePlugin : public VCSBase::VCSBasePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -94,8 +80,6 @@ public:
|
||||
bool vcsOpen(const QString &fileName);
|
||||
bool vcsAdd(const QString &fileName);
|
||||
bool vcsDelete(const QString &filename);
|
||||
// Displays the message for the submit mesage
|
||||
bool editorAboutToClose(Core::IEditor *editor);
|
||||
|
||||
void p4Diff(const QStringList &files, QString diffname = QString());
|
||||
|
||||
@@ -130,11 +114,14 @@ private slots:
|
||||
void filelogCurrentFile();
|
||||
void filelog();
|
||||
|
||||
void updateActions();
|
||||
void submitCurrentLog();
|
||||
void printPendingChanges();
|
||||
void slotDiff(const QStringList &files);
|
||||
|
||||
protected:
|
||||
virtual void updateActions(VCSBase::VCSBasePlugin::ActionState);
|
||||
virtual bool submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor);
|
||||
|
||||
private:
|
||||
QStringList environment() const;
|
||||
|
||||
@@ -163,6 +150,7 @@ private:
|
||||
bool isCommitEditorOpen() const;
|
||||
|
||||
void updateCheckout(const QStringList &dirs = QStringList());
|
||||
inline PerforceVersionControl *perforceVersionControl() const;
|
||||
|
||||
ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer;
|
||||
|
||||
@@ -191,12 +179,11 @@ private:
|
||||
|
||||
QAction *m_undoAction;
|
||||
QAction *m_redoAction;
|
||||
|
||||
QAction *m_menuAction;
|
||||
|
||||
static PerforcePlugin *m_perforcePluginInstance;
|
||||
QString pendingChangesData();
|
||||
|
||||
PerforceVersionControl *m_versionControl;
|
||||
PerforceSettings m_settings;
|
||||
};
|
||||
|
||||
|
@@ -44,19 +44,6 @@ QString PerforceVersionControl::name() const
|
||||
return QLatin1String("perforce");
|
||||
}
|
||||
|
||||
bool PerforceVersionControl::isEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void PerforceVersionControl::setEnabled(bool enabled)
|
||||
{
|
||||
if (m_enabled != enabled) {
|
||||
m_enabled = enabled;
|
||||
emit enabledChanged(m_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
bool PerforceVersionControl::supportsOperation(Operation operation) const
|
||||
{
|
||||
bool rc = true;
|
||||
|
@@ -45,9 +45,6 @@ public:
|
||||
|
||||
virtual QString name() const;
|
||||
|
||||
virtual bool isEnabled() const;
|
||||
virtual void setEnabled(bool enabled);
|
||||
|
||||
bool managesDirectory(const QString &directory) const;
|
||||
virtual QString findTopLevelForDirectory(const QString &directory) const;
|
||||
|
||||
@@ -59,9 +56,6 @@ public:
|
||||
void emitRepositoryChanged(const QString &s);
|
||||
void emitFilesChanged(const QStringList &l);
|
||||
|
||||
signals:
|
||||
void enabledChanged(bool);
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
PerforcePlugin *m_plugin;
|
||||
|
@@ -1323,13 +1323,6 @@ void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node
|
||||
if (projectChanged) {
|
||||
if (debug)
|
||||
qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->name() : "0") << ")";
|
||||
// Enable the right VCS
|
||||
if (const Core::IFile *projectFile = project ? project->file() : static_cast<const Core::IFile *>(0)) {
|
||||
core->vcsManager()->setVCSEnabled(QFileInfo(projectFile->fileName()).absolutePath());
|
||||
} else {
|
||||
core->vcsManager()->setAllVCSEnabled();
|
||||
}
|
||||
|
||||
emit currentProjectChanged(project);
|
||||
updateActions();
|
||||
}
|
||||
|
@@ -44,19 +44,6 @@ QString SubversionControl::name() const
|
||||
return QLatin1String("subversion");
|
||||
}
|
||||
|
||||
bool SubversionControl::isEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void SubversionControl::setEnabled(bool enabled)
|
||||
{
|
||||
if (m_enabled != enabled) {
|
||||
m_enabled = enabled;
|
||||
emit enabledChanged(m_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
bool SubversionControl::supportsOperation(Operation operation) const
|
||||
{
|
||||
bool rc = true;
|
||||
|
@@ -45,9 +45,6 @@ public:
|
||||
explicit SubversionControl(SubversionPlugin *plugin);
|
||||
virtual QString name() const;
|
||||
|
||||
virtual bool isEnabled() const;
|
||||
virtual void setEnabled(bool enabled);
|
||||
|
||||
virtual bool managesDirectory(const QString &directory) const;
|
||||
virtual QString findTopLevelForDirectory(const QString &directory) const;
|
||||
|
||||
@@ -59,9 +56,6 @@ public:
|
||||
void emitRepositoryChanged(const QString &);
|
||||
void emitFilesChanged(const QStringList &);
|
||||
|
||||
signals:
|
||||
void enabledChanged(bool);
|
||||
|
||||
private:
|
||||
bool m_enabled;
|
||||
SubversionPlugin *m_plugin;
|
||||
|
@@ -180,8 +180,8 @@ static inline QStringList svnDirectories()
|
||||
SubversionPlugin *SubversionPlugin::m_subversionPluginInstance = 0;
|
||||
|
||||
SubversionPlugin::SubversionPlugin() :
|
||||
VCSBase::VCSBasePlugin(QLatin1String(Subversion::Constants::SUBVERSIONCOMMITEDITOR_KIND)),
|
||||
m_svnDirectories(svnDirectories()),
|
||||
m_versionControl(0),
|
||||
m_projectExplorer(0),
|
||||
m_addAction(0),
|
||||
m_deleteAction(0),
|
||||
@@ -199,6 +199,7 @@ SubversionPlugin::SubversionPlugin() :
|
||||
m_submitDiffAction(0),
|
||||
m_submitUndoAction(0),
|
||||
m_submitRedoAction(0),
|
||||
m_menuAction(0),
|
||||
m_submitActionTriggered(false)
|
||||
{
|
||||
}
|
||||
@@ -237,10 +238,8 @@ static inline Core::Command *createSeparator(QObject *parent,
|
||||
return ami->registerAction(tmpaction, id, globalcontext);
|
||||
}
|
||||
|
||||
bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *errorMessage)
|
||||
{
|
||||
Q_UNUSED(arguments)
|
||||
|
||||
typedef VCSBase::VCSSubmitEditorFactory<SubversionSubmitEditor> SubversionSubmitEditorFactory;
|
||||
typedef VCSBase::VCSEditorFactory<SubversionEditor> SubversionEditorFactory;
|
||||
using namespace Constants;
|
||||
@@ -248,19 +247,17 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe
|
||||
using namespace Core::Constants;
|
||||
using namespace ExtensionSystem;
|
||||
|
||||
VCSBase::VCSBasePlugin::initialize(new SubversionControl(this));
|
||||
|
||||
m_subversionPluginInstance = this;
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
|
||||
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":/trolltech.subversion/Subversion.mimetypes.xml"), errorMessage))
|
||||
return false;
|
||||
|
||||
m_versionControl = new SubversionControl(this);
|
||||
addAutoReleasedObject(m_versionControl);
|
||||
|
||||
if (QSettings *settings = core->settings())
|
||||
m_settings.fromSettings(settings);
|
||||
|
||||
addAutoReleasedObject(new CoreListener(this));
|
||||
addAutoReleasedObject(new SettingsPage);
|
||||
|
||||
addAutoReleasedObject(new SubversionSubmitEditorFactory(&submitParameters));
|
||||
@@ -280,11 +277,7 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe
|
||||
ami->createMenu(QLatin1String(CMD_ID_SUBVERSION_MENU));
|
||||
subversionMenu->menu()->setTitle(tr("&Subversion"));
|
||||
toolsContainer->addMenu(subversionMenu);
|
||||
if (QAction *ma = subversionMenu->menu()->menuAction()) {
|
||||
ma->setEnabled(m_versionControl->isEnabled());
|
||||
connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
|
||||
}
|
||||
|
||||
m_menuAction = subversionMenu->menu()->menuAction();
|
||||
QList<int> globalcontext;
|
||||
globalcontext << core->uniqueIDManager()->uniqueIdentifier(C_GLOBAL);
|
||||
|
||||
@@ -396,29 +389,21 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe
|
||||
m_submitRedoAction = new QAction(tr("&Redo"), this);
|
||||
command = ami->registerAction(m_submitRedoAction, Core::Constants::REDO, svncommitcontext);
|
||||
|
||||
connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext *)), this, SLOT(updateActions()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SubversionPlugin::extensionsInitialized()
|
||||
{
|
||||
m_projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||
if (m_projectExplorer) {
|
||||
connect(m_projectExplorer,
|
||||
SIGNAL(currentProjectChanged(ProjectExplorer::Project*)),
|
||||
m_subversionPluginInstance, SLOT(updateActions()));
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
bool SubversionPlugin::editorAboutToClose(Core::IEditor *iEditor)
|
||||
bool SubversionPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor)
|
||||
{
|
||||
if ( !iEditor || !isCommitEditorOpen() || qstrcmp(Constants::SUBVERSIONCOMMITEDITOR, iEditor->kind()))
|
||||
if (!isCommitEditorOpen())
|
||||
return true;
|
||||
|
||||
Core::IFile *fileIFace = iEditor->file();
|
||||
const SubversionSubmitEditor *editor = qobject_cast<SubversionSubmitEditor *>(iEditor);
|
||||
Core::IFile *fileIFace = submitEditor->file();
|
||||
const SubversionSubmitEditor *editor = qobject_cast<SubversionSubmitEditor *>(submitEditor);
|
||||
if (!fileIFace || !editor)
|
||||
return true;
|
||||
|
||||
@@ -511,8 +496,11 @@ SubversionSubmitEditor *SubversionPlugin::openSubversionSubmitEditor(const QStri
|
||||
return submitEditor;
|
||||
}
|
||||
|
||||
void SubversionPlugin::updateActions()
|
||||
void SubversionPlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as)
|
||||
{
|
||||
if (!VCSBase::VCSBasePlugin::enableMenuAction(as, m_menuAction))
|
||||
return;
|
||||
|
||||
m_diffProjectAction->setEnabled(true);
|
||||
m_commitAllAction->setEnabled(true);
|
||||
m_statusAction->setEnabled(true);
|
||||
@@ -574,7 +562,7 @@ void SubversionPlugin::revertCurrentFile()
|
||||
const SubversionResponse revertResponse = runSvn(args, subversionShortTimeOut, true);
|
||||
if (!revertResponse.error) {
|
||||
fcb.setModifiedReload(true);
|
||||
m_versionControl->emitFilesChanged(QStringList(file));
|
||||
subVersionControl()->emitFilesChanged(QStringList(file));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,9 +740,10 @@ void SubversionPlugin::updateProject()
|
||||
args.push_back(QLatin1String(nonInteractiveOptionC));
|
||||
args.append(topLevels);
|
||||
const SubversionResponse response = runSvn(args, subversionLongTimeOut, true);
|
||||
if (!response.error)
|
||||
if (!response.error) {
|
||||
foreach(const QString &repo, topLevels)
|
||||
m_versionControl->emitRepositoryChanged(repo);
|
||||
subVersionControl()->emitRepositoryChanged(repo);
|
||||
}
|
||||
}
|
||||
|
||||
void SubversionPlugin::annotateCurrentFile()
|
||||
@@ -1086,4 +1075,9 @@ QString SubversionPlugin::findTopLevelForDirectoryI(const QString &directory) co
|
||||
return QString();
|
||||
}
|
||||
|
||||
SubversionControl *SubversionPlugin::subVersionControl() const
|
||||
{
|
||||
return static_cast<SubversionControl *>(versionControl());
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(SubversionPlugin)
|
||||
|
@@ -32,8 +32,7 @@
|
||||
|
||||
#include "subversionsettings.h"
|
||||
|
||||
#include <coreplugin/icorelistener.h>
|
||||
#include <extensionsystem/iplugin.h>
|
||||
#include <vcsbase/vcsbaseplugin.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDir;
|
||||
@@ -43,6 +42,7 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
class IVersionControl;
|
||||
class IEditor;
|
||||
}
|
||||
namespace Utils {
|
||||
class ParameterAction;
|
||||
@@ -52,6 +52,10 @@ namespace ProjectExplorer {
|
||||
class ProjectExplorerPlugin;
|
||||
}
|
||||
|
||||
namespace VCSBase {
|
||||
class VCSBaseSubmitEditor;
|
||||
}
|
||||
|
||||
namespace Subversion {
|
||||
namespace Internal {
|
||||
|
||||
@@ -67,7 +71,7 @@ struct SubversionResponse
|
||||
QString message;
|
||||
};
|
||||
|
||||
class SubversionPlugin : public ExtensionSystem::IPlugin
|
||||
class SubversionPlugin : public VCSBase::VCSBasePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -77,7 +81,6 @@ public:
|
||||
|
||||
bool initialize(const QStringList &arguments, QString *error_message);
|
||||
void extensionsInitialized();
|
||||
bool editorAboutToClose(Core::IEditor *editor);
|
||||
|
||||
void svnDiff(const QStringList &files, QString diffname = QString());
|
||||
|
||||
@@ -95,7 +98,6 @@ public:
|
||||
static SubversionPlugin *subversionPluginInstance();
|
||||
|
||||
private slots:
|
||||
void updateActions();
|
||||
void addCurrentFile();
|
||||
void deleteCurrentFile();
|
||||
void revertCurrentFile();
|
||||
@@ -112,6 +114,10 @@ private slots:
|
||||
void submitCurrentLog();
|
||||
void diffFiles(const QStringList &);
|
||||
|
||||
protected:
|
||||
virtual void updateActions(VCSBase::VCSBasePlugin::ActionState);
|
||||
virtual bool submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor);
|
||||
|
||||
private:
|
||||
inline bool isCommitEditorOpen() const;
|
||||
QString currentFileName() const;
|
||||
@@ -128,11 +134,11 @@ private:
|
||||
void startCommit(const QStringList &files);
|
||||
bool commit(const QString &messageFile, const QStringList &subVersionFileList);
|
||||
void cleanCommitMessageFile();
|
||||
inline SubversionControl *subVersionControl() const;
|
||||
|
||||
const QStringList m_svnDirectories;
|
||||
|
||||
SubversionSettings m_settings;
|
||||
SubversionControl *m_versionControl;
|
||||
QString m_commitMessageFileName;
|
||||
|
||||
ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer;
|
||||
@@ -154,32 +160,12 @@ private:
|
||||
QAction *m_submitDiffAction;
|
||||
QAction *m_submitUndoAction;
|
||||
QAction *m_submitRedoAction;
|
||||
QAction *m_menuAction;
|
||||
bool m_submitActionTriggered;
|
||||
|
||||
static SubversionPlugin *m_subversionPluginInstance;
|
||||
};
|
||||
|
||||
// Just a proxy for SubversionPlugin
|
||||
class CoreListener : public Core::ICoreListener
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CoreListener(SubversionPlugin *plugin) : m_plugin(plugin) { }
|
||||
|
||||
// Start commit when submit editor closes
|
||||
bool editorAboutToClose(Core::IEditor *editor) {
|
||||
return m_plugin->editorAboutToClose(editor);
|
||||
}
|
||||
|
||||
// TODO: how to handle that ???
|
||||
bool coreAboutToClose() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SubversionPlugin *m_plugin;
|
||||
};
|
||||
|
||||
} // namespace Subversion
|
||||
} // namespace Internal
|
||||
|
||||
|
@@ -28,7 +28,6 @@
|
||||
**************************************************************************/
|
||||
|
||||
#include "basevcseditorfactory.h"
|
||||
#include "vcsbaseplugin.h"
|
||||
#include "vcsbaseeditor.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
|
@@ -5,6 +5,8 @@ include(../../qtcreatorplugin.pri)
|
||||
include(vcsbase_dependencies.pri)
|
||||
HEADERS += vcsbase_global.h \
|
||||
vcsbaseconstants.h \
|
||||
vcsplugin.h \
|
||||
corelistener.h \
|
||||
vcsbaseplugin.h \
|
||||
baseannotationhighlighter.h \
|
||||
diffhighlighter.h \
|
||||
@@ -25,7 +27,9 @@ HEADERS += vcsbase_global.h \
|
||||
basecheckoutwizardpage.h \
|
||||
vcsbaseoutputwindow.h
|
||||
|
||||
SOURCES += vcsbaseplugin.cpp \
|
||||
SOURCES += vcsplugin.cpp \
|
||||
vcsbaseplugin.cpp \
|
||||
corelistener.cpp \
|
||||
baseannotationhighlighter.cpp \
|
||||
diffhighlighter.cpp \
|
||||
vcsbasetextdocument.cpp \
|
||||
|
@@ -630,5 +630,41 @@ bool VCSBaseEditor::gotoLineOfEditor(Core::IEditor *e, int lineNumber)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return source file or directory string depending on parameters
|
||||
// ('git diff XX' -> 'XX' , 'git diff XX file' -> 'XX/file').
|
||||
QString VCSBaseEditor::getSource(const QString &workingDirectory,
|
||||
const QString &fileName)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return workingDirectory;
|
||||
|
||||
QString rc = workingDirectory;
|
||||
const QChar slash = QLatin1Char('/');
|
||||
if (!rc.isEmpty() && !(rc.endsWith(slash) || rc.endsWith(QLatin1Char('\\'))))
|
||||
rc += slash;
|
||||
rc += fileName;
|
||||
return rc;
|
||||
}
|
||||
|
||||
QString VCSBaseEditor::getSource(const QString &workingDirectory,
|
||||
const QStringList &fileNames)
|
||||
{
|
||||
return fileNames.size() == 1 ?
|
||||
getSource(workingDirectory, fileNames.front()) :
|
||||
workingDirectory;
|
||||
}
|
||||
|
||||
QString VCSBaseEditor::getTitleId(const QString &workingDirectory, const QStringList &fileNames)
|
||||
{
|
||||
switch (fileNames.size()) {
|
||||
case 0:
|
||||
return workingDirectory;
|
||||
case 1:
|
||||
return fileNames.front();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return fileNames.join(QLatin1String(", "));
|
||||
}
|
||||
|
||||
} // namespace VCSBase
|
||||
|
@@ -128,6 +128,15 @@ public:
|
||||
//Helper to go to line of editor if it is a text editor
|
||||
static bool gotoLineOfEditor(Core::IEditor *e, int lineNumber);
|
||||
|
||||
// Convenience functions to determine the source to pass on to a diff
|
||||
// editor if one has a call consisting of working directory and file arguments.
|
||||
// ('git diff XX' -> 'XX' , 'git diff XX file' -> 'XX/file').
|
||||
static QString getSource(const QString &workingDirectory, const QString &fileName);
|
||||
static QString getSource(const QString &workingDirectory, const QStringList &fileNames);
|
||||
// Convenience functions to determine an title/id to identify the editor
|
||||
// from the arguments (','-joined arguments or directory).
|
||||
static QString getTitleId(const QString &workingDirectory, const QStringList &fileNames);
|
||||
|
||||
signals:
|
||||
void describeRequested(const QString &source, const QString &change);
|
||||
|
||||
|
@@ -28,97 +28,420 @@
|
||||
**************************************************************************/
|
||||
|
||||
#include "vcsbaseplugin.h"
|
||||
#include "diffhighlighter.h"
|
||||
#include "vcsbasesettingspage.h"
|
||||
#include "nicknamedialog.h"
|
||||
#include "vcsbaseoutputwindow.h"
|
||||
#include "vcsbasesubmiteditor.h"
|
||||
#include "vcsplugin.h"
|
||||
#include "corelistener.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/uniqueidmanager.h>
|
||||
#include <coreplugin/mimedatabase.h>
|
||||
#include <coreplugin/ifile.h>
|
||||
#include <coreplugin/iversioncontrol.h>
|
||||
#include <coreplugin/filemanager.h>
|
||||
#include <coreplugin/vcsmanager.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QSharedData>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
namespace VCSBase {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
VCSBasePlugin *VCSBasePlugin::m_instance = 0;
|
||||
// Internal state created by the state listener and
|
||||
// VCSBasePluginState.
|
||||
|
||||
VCSBasePlugin::VCSBasePlugin() :
|
||||
m_settingsPage(0),
|
||||
m_nickNameModel(0)
|
||||
struct State {
|
||||
void clearFile();
|
||||
void clearProject();
|
||||
inline void clear();
|
||||
|
||||
bool equals(const State &rhs) const;
|
||||
|
||||
inline bool hasFile() const { return !currentFile.isEmpty(); }
|
||||
inline bool hasProject() const { return !currentProjectPath.isEmpty(); }
|
||||
inline bool isEmpty() const { return !hasFile() && !hasProject(); }
|
||||
|
||||
QString currentFile;
|
||||
QString currentFileName;
|
||||
QString currentFileDirectory;
|
||||
QString currentFileTopLevel;
|
||||
|
||||
QString currentProjectPath;
|
||||
QString currentProjectName;
|
||||
QString currentProjectTopLevel;
|
||||
};
|
||||
|
||||
void State::clearFile()
|
||||
{
|
||||
currentFile.clear();
|
||||
currentFileName.clear();
|
||||
currentFileDirectory.clear();
|
||||
currentFileTopLevel.clear();
|
||||
}
|
||||
|
||||
void State::clearProject()
|
||||
{
|
||||
currentProjectPath.clear();
|
||||
currentProjectName.clear();
|
||||
currentProjectTopLevel.clear();
|
||||
}
|
||||
|
||||
void State::clear()
|
||||
{
|
||||
clearFile();
|
||||
clearProject();
|
||||
}
|
||||
|
||||
bool State::equals(const State &rhs) const
|
||||
{
|
||||
return currentFile == rhs.currentFile
|
||||
&& currentFileName == rhs.currentFileName
|
||||
&& currentFileTopLevel == rhs.currentFileTopLevel
|
||||
&& currentProjectPath == rhs.currentProjectPath
|
||||
&& currentProjectName == rhs.currentProjectName
|
||||
&& currentProjectTopLevel == rhs.currentProjectTopLevel;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug in, const State &state)
|
||||
{
|
||||
QDebug nospace = in.nospace();
|
||||
nospace << "State: ";
|
||||
if (state.isEmpty()) {
|
||||
nospace << "<empty>";
|
||||
} else {
|
||||
if (state.hasFile()) {
|
||||
nospace << "File=" << state.currentFile
|
||||
<< ',' << state.currentFileTopLevel;
|
||||
} else {
|
||||
nospace << "<no file>";
|
||||
}
|
||||
nospace << '\n';
|
||||
if (state.hasProject()) {
|
||||
nospace << " Project=" << state.currentProjectName
|
||||
<< ',' << state.currentProjectPath
|
||||
<< ',' << state.currentProjectTopLevel;
|
||||
|
||||
} else {
|
||||
nospace << "<no project>";
|
||||
}
|
||||
nospace << '\n';
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
// StateListener: Connects to the relevant signals, tries to find version
|
||||
// controls and emits signals to the plugin instances.
|
||||
|
||||
class StateListener : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit StateListener(QObject *parent);
|
||||
|
||||
signals:
|
||||
void stateChanged(const VCSBase::Internal::State &s, Core::IVersionControl *vc);
|
||||
|
||||
private slots:
|
||||
void slotStateChanged();
|
||||
};
|
||||
|
||||
StateListener::StateListener(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
connect(core, SIGNAL(contextChanged(Core::IContext *)),
|
||||
this, SLOT(slotStateChanged()));
|
||||
connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
|
||||
this, SLOT(slotStateChanged()));
|
||||
|
||||
if (ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance())
|
||||
connect(pe, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)),
|
||||
this, SLOT(slotStateChanged()));
|
||||
}
|
||||
|
||||
void StateListener::slotStateChanged()
|
||||
{
|
||||
const ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||
const Core::ICore *core = Core::ICore::instance();
|
||||
Core::VCSManager *vcsManager = core->vcsManager();
|
||||
|
||||
// Get the current file. Are we on a temporary submit editor or something? Ignore.
|
||||
State state;
|
||||
state.currentFile = core->fileManager()->currentFile();
|
||||
if (!state.currentFile.isEmpty() && state.currentFile.startsWith(QDir::tempPath()))
|
||||
state.currentFile.clear();
|
||||
// Get the file and its control. Do not use the file unless we find one
|
||||
Core::IVersionControl *fileControl = 0;
|
||||
if (!state.currentFile.isEmpty()) {
|
||||
const QFileInfo fi(state.currentFile);
|
||||
state.currentFileDirectory = fi.absolutePath();
|
||||
state.currentFileName = fi.fileName();
|
||||
fileControl = vcsManager->findVersionControlForDirectory(state.currentFileDirectory,
|
||||
&state.currentFileTopLevel);
|
||||
if (!fileControl)
|
||||
state.clearFile();
|
||||
}
|
||||
// Check for project, find the control
|
||||
Core::IVersionControl *projectControl = 0;
|
||||
if (const ProjectExplorer::Project *currentProject = pe->currentProject()) {
|
||||
state.currentProjectPath = QFileInfo(currentProject->file()->fileName()).absolutePath();
|
||||
state.currentProjectName = currentProject->name();
|
||||
projectControl = vcsManager->findVersionControlForDirectory(state.currentProjectPath,
|
||||
&state.currentProjectTopLevel);
|
||||
if (projectControl) {
|
||||
// If we have both, let the file's one take preference
|
||||
if (fileControl && projectControl != fileControl) {
|
||||
state.clearProject();
|
||||
}
|
||||
} else {
|
||||
state.clearProject(); // No control found
|
||||
}
|
||||
}
|
||||
// Assemble state and emit signal.
|
||||
Core::IVersionControl *vc = state.currentFile.isEmpty() ? projectControl : fileControl;
|
||||
if (debug)
|
||||
qDebug() << state << (vc ? vc->name() : QString(QLatin1String("No version control")));
|
||||
emit stateChanged(state, vc);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
class VCSBasePluginStateData : public QSharedData {
|
||||
public:
|
||||
Internal::State m_state;
|
||||
};
|
||||
|
||||
VCSBasePluginState::VCSBasePluginState() : data(new VCSBasePluginStateData)
|
||||
{
|
||||
}
|
||||
|
||||
VCSBasePluginState::VCSBasePluginState(const VCSBasePluginState &rhs) : data(rhs.data)
|
||||
{
|
||||
}
|
||||
|
||||
VCSBasePluginState &VCSBasePluginState::operator=(const VCSBasePluginState &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
data.operator=(rhs.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
VCSBasePluginState::~VCSBasePluginState()
|
||||
{
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::currentFile() const
|
||||
{
|
||||
return data->m_state.currentFile;
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::currentFileName() const
|
||||
{
|
||||
return data->m_state.currentFileName;
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::currentFileTopLevel() const
|
||||
{
|
||||
return data->m_state.currentFileTopLevel;
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::currentFileDirectory() const
|
||||
{
|
||||
return data->m_state.currentFileDirectory;
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::relativeCurrentFile() const
|
||||
{
|
||||
QTC_ASSERT(hasFile(), return QString())
|
||||
return QDir(data->m_state.currentFileTopLevel).relativeFilePath(data->m_state.currentFile);
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::currentProjectPath() const
|
||||
{
|
||||
return data->m_state.currentProjectPath;
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::currentProjectName() const
|
||||
{
|
||||
return data->m_state.currentProjectName;
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::currentProjectTopLevel() const
|
||||
{
|
||||
return data->m_state.currentProjectTopLevel;
|
||||
}
|
||||
|
||||
QStringList VCSBasePluginState::relativeCurrentProject() const
|
||||
{
|
||||
QStringList rc;
|
||||
QTC_ASSERT(hasProject(), return rc)
|
||||
if (data->m_state.currentProjectTopLevel != data->m_state.currentProjectPath)
|
||||
rc.append(QDir(data->m_state.currentProjectTopLevel).relativeFilePath(data->m_state.currentProjectPath));
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool VCSBasePluginState::hasTopLevel() const
|
||||
{
|
||||
return data->m_state.hasFile() || data->m_state.hasProject();
|
||||
}
|
||||
|
||||
QString VCSBasePluginState::topLevel() const
|
||||
{
|
||||
return hasFile() ? data->m_state.currentFileTopLevel : data->m_state.currentProjectTopLevel;
|
||||
}
|
||||
|
||||
bool VCSBasePluginState::equals(const Internal::State &rhs) const
|
||||
{
|
||||
return data->m_state.equals(rhs);
|
||||
}
|
||||
|
||||
bool VCSBasePluginState::equals(const VCSBasePluginState &rhs) const
|
||||
{
|
||||
return equals(rhs.data->m_state);
|
||||
}
|
||||
|
||||
void VCSBasePluginState::clear()
|
||||
{
|
||||
data->m_state.clear();
|
||||
}
|
||||
|
||||
void VCSBasePluginState::setState(const Internal::State &s)
|
||||
{
|
||||
data->m_state = s;
|
||||
}
|
||||
|
||||
bool VCSBasePluginState::isEmpty() const
|
||||
{
|
||||
return data->m_state.isEmpty();
|
||||
}
|
||||
|
||||
bool VCSBasePluginState::hasFile() const
|
||||
{
|
||||
return data->m_state.hasFile();
|
||||
}
|
||||
|
||||
bool VCSBasePluginState::hasProject() const
|
||||
{
|
||||
return data->m_state.hasProject();
|
||||
}
|
||||
|
||||
VCSBASE_EXPORT QDebug operator<<(QDebug in, const VCSBasePluginState &state)
|
||||
{
|
||||
in << state.data->m_state;
|
||||
return in;
|
||||
}
|
||||
|
||||
// VCSBasePlugin
|
||||
struct VCSBasePluginPrivate {
|
||||
explicit VCSBasePluginPrivate(const QString &submitEditorKind);
|
||||
|
||||
const QString m_submitEditorKind;
|
||||
Core::IVersionControl *m_versionControl;
|
||||
VCSBasePluginState m_state;
|
||||
int m_actionState;
|
||||
|
||||
static Internal::StateListener *m_listener;
|
||||
};
|
||||
|
||||
VCSBasePluginPrivate::VCSBasePluginPrivate(const QString &submitEditorKind) :
|
||||
m_submitEditorKind(submitEditorKind),
|
||||
m_versionControl(0),
|
||||
m_actionState(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Internal::StateListener *VCSBasePluginPrivate::m_listener = 0;
|
||||
|
||||
VCSBasePlugin::VCSBasePlugin(const QString &submitEditorKind) :
|
||||
d(new VCSBasePluginPrivate(submitEditorKind))
|
||||
{
|
||||
m_instance = this;
|
||||
}
|
||||
|
||||
VCSBasePlugin::~VCSBasePlugin()
|
||||
{
|
||||
m_instance = 0;
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool VCSBasePlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
void VCSBasePlugin::initialize(Core::IVersionControl *vc)
|
||||
{
|
||||
Q_UNUSED(arguments)
|
||||
Q_UNUSED(errorMessage)
|
||||
d->m_versionControl = vc;
|
||||
addAutoReleasedObject(vc);
|
||||
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":/vcsbase/VCSBase.mimetypes.xml"), errorMessage))
|
||||
Internal::VCSPlugin *plugin = Internal::VCSPlugin::instance();
|
||||
connect(plugin->coreListener(), SIGNAL(submitEditorAboutToClose(VCSBaseSubmitEditor*,bool*)),
|
||||
this, SLOT(slotSubmitEditorAboutToClose(VCSBaseSubmitEditor*,bool*)));
|
||||
// First time: create new listener
|
||||
if (!VCSBasePluginPrivate::m_listener)
|
||||
VCSBasePluginPrivate::m_listener = new Internal::StateListener(plugin);
|
||||
connect(VCSBasePluginPrivate::m_listener,
|
||||
SIGNAL(stateChanged(VCSBase::Internal::State, Core::IVersionControl*)),
|
||||
this,
|
||||
SLOT(slotStateChanged(VCSBase::Internal::State,Core::IVersionControl*)));
|
||||
}
|
||||
|
||||
void VCSBasePlugin::slotSubmitEditorAboutToClose(VCSBaseSubmitEditor *submitEditor, bool *result)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << this << d->m_submitEditorKind << "Closing submit editor" << submitEditor << submitEditor->kind();
|
||||
if (submitEditor->kind() == d->m_submitEditorKind)
|
||||
*result = submitEditorAboutToClose(submitEditor);
|
||||
}
|
||||
|
||||
Core::IVersionControl *VCSBasePlugin::versionControl() const
|
||||
{
|
||||
return d->m_versionControl;
|
||||
}
|
||||
|
||||
void VCSBasePlugin::slotStateChanged(const VCSBase::Internal::State &newInternalState, Core::IVersionControl *vc)
|
||||
{
|
||||
if (vc == d->m_versionControl) {
|
||||
// We are directly affected: Change state
|
||||
if (!d->m_state.equals(newInternalState)) {
|
||||
d->m_state.setState(newInternalState);
|
||||
updateActions(VCSEnabled);
|
||||
}
|
||||
} else {
|
||||
// Some other VCS plugin or state changed: Reset us to empty state.
|
||||
const ActionState newActionState = vc ? OtherVCSEnabled : NoVCSEnabled;
|
||||
if (d->m_actionState != newActionState || !d->m_state.isEmpty()) {
|
||||
d->m_actionState = newActionState;
|
||||
const VCSBasePluginState emptyState;
|
||||
d->m_state = emptyState;
|
||||
updateActions(newActionState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const VCSBasePluginState &VCSBasePlugin::currentState() const
|
||||
{
|
||||
return d->m_state;
|
||||
}
|
||||
|
||||
bool VCSBasePlugin::enableMenuAction(ActionState as, QAction *menuAction)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << "enableMenuAction" << menuAction->text() << as;
|
||||
switch (as) {
|
||||
case VCSBase::VCSBasePlugin::NoVCSEnabled:
|
||||
menuAction->setVisible(true);
|
||||
menuAction->setEnabled(false);
|
||||
return false;
|
||||
|
||||
m_settingsPage = new VCSBaseSettingsPage;
|
||||
addAutoReleasedObject(m_settingsPage);
|
||||
addAutoReleasedObject(VCSBaseOutputWindow::instance());
|
||||
connect(m_settingsPage, SIGNAL(settingsChanged(VCSBase::Internal::VCSBaseSettings)),
|
||||
this, SIGNAL(settingsChanged(VCSBase::Internal::VCSBaseSettings)));
|
||||
connect(m_settingsPage, SIGNAL(settingsChanged(VCSBase::Internal::VCSBaseSettings)),
|
||||
this, SLOT(slotSettingsChanged()));
|
||||
slotSettingsChanged();
|
||||
case VCSBase::VCSBasePlugin::OtherVCSEnabled:
|
||||
menuAction->setVisible(false);
|
||||
return false;
|
||||
case VCSBase::VCSBasePlugin::VCSEnabled:
|
||||
menuAction->setVisible(true);
|
||||
menuAction->setEnabled(true);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VCSBasePlugin::extensionsInitialized()
|
||||
{
|
||||
}
|
||||
|
||||
VCSBasePlugin *VCSBasePlugin::instance()
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
VCSBaseSettings VCSBasePlugin::settings() const
|
||||
{
|
||||
return m_settingsPage->settings();
|
||||
}
|
||||
|
||||
/* Delayed creation/update of the nick name model. */
|
||||
QStandardItemModel *VCSBasePlugin::nickNameModel()
|
||||
{
|
||||
if (!m_nickNameModel) {
|
||||
m_nickNameModel = NickNameDialog::createModel(this);
|
||||
populateNickNameModel();
|
||||
}
|
||||
return m_nickNameModel;
|
||||
}
|
||||
|
||||
void VCSBasePlugin::populateNickNameModel()
|
||||
{
|
||||
QString errorMessage;
|
||||
if (!NickNameDialog::populateModelFromMailCapFile(settings().nickNameMailMap,
|
||||
m_nickNameModel,
|
||||
&errorMessage)) {
|
||||
qWarning("%s", qPrintable(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
void VCSBasePlugin::slotSettingsChanged()
|
||||
{
|
||||
if (m_nickNameModel)
|
||||
populateNickNameModel();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace VCSBase
|
||||
|
||||
Q_EXPORT_PLUGIN(VCSBase::Internal::VCSBasePlugin)
|
||||
#include "vcsbaseplugin.moc"
|
||||
|
@@ -30,56 +30,146 @@
|
||||
#ifndef VCSBASEPLUGIN_H
|
||||
#define VCSBASEPLUGIN_H
|
||||
|
||||
#include "vcsbase_global.h"
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QSharedDataPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QStandardItemModel;
|
||||
class QAction;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
class IVersionControl;
|
||||
}
|
||||
|
||||
namespace VCSBase {
|
||||
namespace Internal {
|
||||
struct State;
|
||||
}
|
||||
|
||||
struct VCSBaseSettings;
|
||||
class VCSBaseSettingsPage;
|
||||
class VCSBaseSubmitEditor;
|
||||
struct VCSBasePluginPrivate;
|
||||
class VCSBasePluginStateData;
|
||||
class VCSBasePlugin;
|
||||
|
||||
class VCSBasePlugin : public ExtensionSystem::IPlugin
|
||||
/* VCSBasePlugin and VCSBasePluginState: Provide a base class for
|
||||
* VCS plugins. It mainly takes care of maintaining the
|
||||
* VCS-relevant state of Qt Creator which is a tuple of
|
||||
*
|
||||
* 1) Current file and it's version system control/top level
|
||||
* 2) Current project and it's version system control/top level
|
||||
*
|
||||
* (reflected in VCSBasePluginState). The plugin connects to the
|
||||
* relevant change signals in Qt Creator and calls the virtual
|
||||
* updateActions() for the plugins to update their menu actions
|
||||
* according to the new state. This is done centrally to avoid
|
||||
* single plugins repeatedly invoking searches/QFileInfo on files,
|
||||
* etc.
|
||||
*
|
||||
* If current file/project are managed
|
||||
* by different version controls, the project is discarded and only
|
||||
* the current file is taken into account, allowing to do a diff
|
||||
* also when the project of a file is not opened.
|
||||
*
|
||||
* When triggering an action, a copy of the state should be made to
|
||||
* keep it, as it may rapidly change due to context changes, etc.
|
||||
*
|
||||
* The class also detects the VCS plugin submit editor closing and calls
|
||||
* the virtual submitEditorAboutToClose() to trigger the submit process. */
|
||||
|
||||
class VCSBASE_EXPORT VCSBasePluginState
|
||||
{
|
||||
public:
|
||||
VCSBasePluginState();
|
||||
VCSBasePluginState(const VCSBasePluginState &);
|
||||
VCSBasePluginState &operator=(const VCSBasePluginState &);
|
||||
~VCSBasePluginState();
|
||||
|
||||
void clear();
|
||||
|
||||
bool isEmpty() const;
|
||||
bool hasFile() const;
|
||||
bool hasProject() const;
|
||||
bool hasTopLevel() const;
|
||||
|
||||
// Current file.
|
||||
QString currentFile() const;
|
||||
QString currentFileName() const;
|
||||
QString currentFileDirectory() const;
|
||||
QString currentFileTopLevel() const;
|
||||
// Convenience: Returns file relative to top level.
|
||||
QString relativeCurrentFile() const;
|
||||
|
||||
// Current project.
|
||||
QString currentProjectPath() const;
|
||||
QString currentProjectName() const;
|
||||
QString currentProjectTopLevel() const;
|
||||
/* Convenience: Returns project path relative to top level if it
|
||||
* differs from top level (else empty()) as an argument list to do
|
||||
* eg a 'vcs diff <args>' */
|
||||
QStringList relativeCurrentProject() const;
|
||||
|
||||
// Top level directory for actions on the top level. Preferably
|
||||
// the file one.
|
||||
QString topLevel() const;
|
||||
|
||||
bool equals(const VCSBasePluginState &rhs) const;
|
||||
|
||||
friend VCSBASE_EXPORT QDebug operator<<(QDebug in, const VCSBasePluginState &state);
|
||||
|
||||
private:
|
||||
friend class VCSBasePlugin;
|
||||
bool equals(const Internal::State &s) const;
|
||||
void setState(const Internal::State &s);
|
||||
|
||||
QSharedDataPointer<VCSBasePluginStateData> data;
|
||||
};
|
||||
|
||||
VCSBASE_EXPORT QDebug operator<<(QDebug in, const VCSBasePluginState &state);
|
||||
|
||||
inline bool operator==(const VCSBasePluginState &s1, const VCSBasePluginState &s2)
|
||||
{ return s1.equals(s2); }
|
||||
inline bool operator!=(const VCSBasePluginState &s1, const VCSBasePluginState &s2)
|
||||
{ return !s1.equals(s2); }
|
||||
|
||||
class VCSBASE_EXPORT VCSBasePlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
explicit VCSBasePlugin(const QString &submitEditorKind);
|
||||
|
||||
void initialize(Core::IVersionControl *vc);
|
||||
Core::IVersionControl *versionControl() const;
|
||||
|
||||
public:
|
||||
VCSBasePlugin();
|
||||
~VCSBasePlugin();
|
||||
virtual ~VCSBasePlugin();
|
||||
|
||||
bool initialize(const QStringList &arguments, QString *error_message);
|
||||
const VCSBasePluginState ¤tState() const;
|
||||
|
||||
void extensionsInitialized();
|
||||
protected:
|
||||
enum ActionState { NoVCSEnabled, OtherVCSEnabled, VCSEnabled };
|
||||
|
||||
static VCSBasePlugin *instance();
|
||||
// Implement to enable the plugin menu actions according to state.
|
||||
virtual void updateActions(ActionState as) = 0;
|
||||
// Implement to start the submit process.
|
||||
virtual bool submitEditorAboutToClose(VCSBaseSubmitEditor *submitEditor) = 0;
|
||||
|
||||
VCSBaseSettings settings() const;
|
||||
|
||||
// Model of user nick names used for the submit
|
||||
// editor. Stored centrally here to achieve delayed
|
||||
// initialization and updating on settings change.
|
||||
QStandardItemModel *nickNameModel();
|
||||
|
||||
signals:
|
||||
void settingsChanged(const VCSBase::Internal::VCSBaseSettings& s);
|
||||
// A helper to enable the VCS menu action according to state:
|
||||
// NoVCSEnabled->(visible,disabled), OtherVCSEnabled->(invisible), else
|
||||
// enabled. Returns whether actions should be set up further.
|
||||
static bool enableMenuAction(ActionState as, QAction *in);
|
||||
|
||||
private slots:
|
||||
void slotSettingsChanged();
|
||||
void slotSubmitEditorAboutToClose(VCSBaseSubmitEditor *submitEditor, bool *result);
|
||||
void slotStateChanged(const VCSBase::Internal::State &s, Core::IVersionControl *vc);
|
||||
|
||||
private:
|
||||
void populateNickNameModel();
|
||||
|
||||
static VCSBasePlugin *m_instance;
|
||||
VCSBaseSettingsPage *m_settingsPage;
|
||||
QStandardItemModel *m_nickNameModel;
|
||||
VCSBasePluginPrivate *d;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace VCSBase
|
||||
|
||||
#endif // VCSBASEPLUGIN_H
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "vcsbasesubmiteditor.h"
|
||||
#include "vcsbasesettings.h"
|
||||
#include "vcsbaseplugin.h"
|
||||
#include "vcsplugin.h"
|
||||
#include "nicknamedialog.h"
|
||||
#include "submiteditorfile.h"
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace VCSBase {
|
||||
|
||||
static inline QString submitMessageCheckScript()
|
||||
{
|
||||
return Internal::VCSBasePlugin::instance()->settings().submitMessageCheckScript;
|
||||
return Internal::VCSPlugin::instance()->settings().submitMessageCheckScript;
|
||||
}
|
||||
|
||||
struct VCSBaseSubmitEditorPrivate
|
||||
@@ -127,7 +127,7 @@ VCSBaseSubmitEditor::VCSBaseSubmitEditor(const VCSBaseSubmitEditorParameters *pa
|
||||
connect(m_d->m_widget, SIGNAL(diffSelected(QStringList)), this, SLOT(slotDiffSelectedVCSFiles(QStringList)));
|
||||
connect(m_d->m_widget->descriptionEdit(), SIGNAL(textChanged()), this, SLOT(slotDescriptionChanged()));
|
||||
|
||||
const Internal::VCSBaseSettings settings = Internal::VCSBasePlugin::instance()->settings();
|
||||
const Internal::VCSBaseSettings settings = Internal::VCSPlugin::instance()->settings();
|
||||
// Add additional context menu settings
|
||||
if (!settings.submitMessageCheckScript.isEmpty() || !settings.nickNameMailMap.isEmpty()) {
|
||||
QAction *sep = new QAction(this);
|
||||
@@ -152,7 +152,7 @@ VCSBaseSubmitEditor::VCSBaseSubmitEditor(const VCSBaseSubmitEditorParameters *pa
|
||||
|
||||
// wrapping. etc
|
||||
slotUpdateEditorSettings(settings);
|
||||
connect(Internal::VCSBasePlugin::instance(),
|
||||
connect(Internal::VCSPlugin::instance(),
|
||||
SIGNAL(settingsChanged(VCSBase::Internal::VCSBaseSettings)),
|
||||
this, SLOT(slotUpdateEditorSettings(VCSBase::Internal::VCSBaseSettings)));
|
||||
|
||||
@@ -199,7 +199,7 @@ void VCSBaseSubmitEditor::createUserFields(const QString &fieldConfigFile)
|
||||
if (fields.empty())
|
||||
return;
|
||||
// Create a completer on user names
|
||||
const QStandardItemModel *nickNameModel = Internal::VCSBasePlugin::instance()->nickNameModel();
|
||||
const QStandardItemModel *nickNameModel = Internal::VCSPlugin::instance()->nickNameModel();
|
||||
QCompleter *completer = new QCompleter(Internal::NickNameDialog::nickNameList(nickNameModel), this);
|
||||
|
||||
Utils::SubmitFieldWidget *fieldWidget = new Utils::SubmitFieldWidget;
|
||||
@@ -487,7 +487,7 @@ VCSBaseSubmitEditor::PromptSubmitResult
|
||||
QString VCSBaseSubmitEditor::promptForNickName()
|
||||
{
|
||||
if (!m_d->m_nickNameDialog)
|
||||
m_d->m_nickNameDialog = new Internal::NickNameDialog(Internal::VCSBasePlugin::instance()->nickNameModel(), m_d->m_widget);
|
||||
m_d->m_nickNameDialog = new Internal::NickNameDialog(Internal::VCSPlugin::instance()->nickNameModel(), m_d->m_widget);
|
||||
if (m_d->m_nickNameDialog->exec() == QDialog::Accepted)
|
||||
return m_d->m_nickNameDialog->nickName();
|
||||
return QString();
|
||||
|
Reference in New Issue
Block a user