Initial import

This commit is contained in:
con
2008-12-02 12:01:29 +01:00
commit 05c35356ab
1675 changed files with 229938 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
<plugin name="ScmGit" version="0.1" compatVersion="0.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>
<description>Git integration.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="ProjectExplorer" version="0.9.1"/>
<dependency name="Core" version="0.9.1"/>
<dependency name="VCSBase" version="0.9.1"/>
</dependencyList>
</plugin>

26
src/plugins/git/TODO.txt Normal file
View File

@@ -0,0 +1,26 @@
- Make texts translateable
- Do not use QErrorMessage, Creator standard error instead?
Commands:
- P2:
- branch [list, create, delete]
- checkout [with/without creation]
- combine both above to a single dialog?
- P3:
- stash [creating, listing, applying]
- allow to use external viewer instead of greenhouse one
as these have more functionality usually
GUI:
- Better diff view
- Commit view View (reuse diff view?)
- Commit action View
- Able to add further files to commit (list of modified/untracked files)
- use List for Log (and allow 10+ entries)
- Have commits clickable for 'git show'
Backend:
- Don't use forked processes, instead find a library connection like libgit-thin
- http://repo.or.cz/w/git/libgit-gsoc.git
- apply to SCM Manager in Greenhouse, currently it's mostly independent
Suggestions:
- Bjorn: Use a "Summary" Lineedit in the commit dialog to make commits look nicer on gitweb or such.

View File

@@ -0,0 +1,53 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "annotationhighlighter.h"
#include <QtCore/QDebug>
namespace Git {
namespace Internal {
GitAnnotationHighlighter::GitAnnotationHighlighter(const ChangeNumbers &changeNumbers,
QTextDocument *document) :
VCSBase::BaseAnnotationHighlighter(changeNumbers, document),
m_blank(QLatin1Char(' '))
{
}
QString GitAnnotationHighlighter::changeNumber(const QString &block) const
{
const int pos = block.indexOf(m_blank, 4);
return pos > 1 ? block.left(pos) : QString();
}
}
}

View File

@@ -0,0 +1,58 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef ANNOTATIONHIGHLIGHTER_H
#define ANNOTATIONHIGHLIGHTER_H
#include <vcsbase/baseannotationhighlighter.h>
namespace Git {
namespace Internal {
// Annotation highlighter for p4 triggering on 'changenumber:'
class GitAnnotationHighlighter : public VCSBase::BaseAnnotationHighlighter
{
Q_OBJECT
public:
explicit GitAnnotationHighlighter(const ChangeNumbers &changeNumbers,
QTextDocument *document = 0);
private:
virtual QString changeNumber(const QString &block) const;
const QChar m_blank;
};
} //namespace Git
} //namespace Internal
#endif

View File

@@ -0,0 +1,71 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "changeselectiondialog.h"
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
using namespace Git::Internal;
ChangeSelectionDialog::ChangeSelectionDialog(QWidget *parent)
: QDialog(parent)
{
m_ui.setupUi(this);
connect(m_ui.repositoryButton, SIGNAL(clicked()), this, SLOT(selectWorkingDirectory()));
}
void ChangeSelectionDialog::selectWorkingDirectory()
{
static QString location = QString();
location = QFileDialog::getExistingDirectory(this,
QLatin1String("Select Git repository"),
location);
if (location.isEmpty())
return;
// Verify that the location is a repository
// We are polite, we also allow to specify a directory, which is not
// the head directory of the repository.
QDir repository(location);
do {
if (repository.entryList(QDir::AllDirs).contains(QLatin1String(".git"))) {
m_ui.repositoryEdit->setText(repository.absolutePath());
return;
}
} while (repository.cdUp());
// Did not find a repo
QMessageBox::critical(this, QLatin1String("Error"),
QLatin1String("Selected directory is not a Git repository"));
}

View File

@@ -0,0 +1,63 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef CHANGESELECTIONDIALOG_H
#define CHANGESELECTIONDIALOG_H
#include <QtGui/QDialog>
#include "ui_changeselectiondialog.h"
namespace Git {
namespace Internal {
class GitPlugin;
class ChangeSelectionDialog : public QDialog
{
Q_OBJECT
public:
ChangeSelectionDialog(QWidget *parent = 0);
public slots:
void selectWorkingDirectory();
private:
friend class GitPlugin;
Ui_ChangeSelectionDialog m_ui;
};
} //namespace Internal
} //namespace Git
#endif // CHANGESELECTIONDIALOG_H

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChangeSelectionDialog</class>
<widget class="QDialog" name="ChangeSelectionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>401</width>
<height>142</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Repository Location:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="repositoryEdit"/>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="repositoryButton">
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Change:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="changeNumberEdit"/>
</item>
<item row="2" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ChangeSelectionDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ChangeSelectionDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,96 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "commitdata.h"
#include <QtCore/QDebug>
namespace Git {
namespace Internal {
void GitSubmitEditorPanelInfo::clear()
{
repository.clear();
description.clear();
branch.clear();
}
QDebug operator<<(QDebug d, const GitSubmitEditorPanelInfo &data)
{
d.nospace() << "Rep: " << data.repository << " Descr: " << data.description
<< " branch: " << data.branch;
return d;
}
void GitSubmitEditorPanelData::clear()
{
author.clear();
email.clear();
}
QString GitSubmitEditorPanelData::authorString() const
{
QString rc;
rc += QLatin1Char('"');
rc += author;
rc += QLatin1String(" <");
rc += email;
rc += QLatin1String(">\"");
return rc;
}
QDebug operator<<(QDebug d, const GitSubmitEditorPanelData &data)
{
d.nospace() << " author:" << data.author << " email: " << data.email;
return d;
}
void CommitData::clear()
{
panelInfo.clear();
panelData.clear();
commitFiles.clear();
notUpdatedFiles.clear();
untrackedFiles.clear();
}
QDebug operator<<(QDebug d, const CommitData &data)
{
d << data.panelInfo << data.panelData;
d.nospace() << "Commit: " << data.commitFiles << " Not updated: "
<< data.notUpdatedFiles << " Untracked: " << data.untrackedFiles;
return d;
}
}
}

View File

@@ -0,0 +1,81 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef COMMITDATA_H
#define COMMITDATA_H
#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
class QDebug;
QT_END_NAMESPACE
namespace Git {
namespace Internal {
// Read-only
struct GitSubmitEditorPanelInfo {
void clear();
QString repository;
QString description;
QString branch;
};
QDebug operator<<(QDebug d, const GitSubmitEditorPanelInfo &);
struct GitSubmitEditorPanelData {
void clear();
// Format as "John Doe <jdoe@foobar.com>"
QString authorString() const;
QString author;
QString email;
};
QDebug operator<<(QDebug d, const GitSubmitEditorPanelData &);
struct CommitData {
void clear();
GitSubmitEditorPanelInfo panelInfo;
GitSubmitEditorPanelData panelData;
QStringList commitFiles;
QStringList notUpdatedFiles;
QStringList untrackedFiles;
};
QDebug operator<<(QDebug d, const CommitData &);
}
}
#endif

35
src/plugins/git/git.pro Normal file
View File

@@ -0,0 +1,35 @@
TEMPLATE = lib
TARGET = ScmGit
include(../../qworkbenchplugin.pri)
include(../../plugins/projectexplorer/projectexplorer.pri)
include(../../plugins/texteditor/texteditor.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/vcsbase/vcsbase.pri)
include(../../libs/utils/utils.pri)
HEADERS += gitplugin.h \
gitconstants.h \
gitoutputwindow.h \
gitclient.h \
changeselectiondialog.h \
commitdata.h \
settingspage.h \
giteditor.h \
annotationhighlighter.h \
gitsubmiteditorwidget.h \
gitsubmiteditor.h
SOURCES += gitplugin.cpp \
gitoutputwindow.cpp \
gitclient.cpp \
changeselectiondialog.cpp \
commitdata.cpp \
settingspage.cpp \
giteditor.cpp \
annotationhighlighter.cpp \
gitsubmiteditorwidget.cpp \
gitsubmiteditor.cpp
FORMS += changeselectiondialog.ui \
settingspage.ui \
gitsubmitpanel.ui

View File

@@ -0,0 +1,635 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gitclient.h"
#include "gitplugin.h"
#include "gitconstants.h"
#include "commitdata.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanagerinterface.h>
#include <vcsbase/vcsbaseeditor.h>
#include <texteditor/itexteditor.h>
#include <QtCore/QRegExp>
#include <QtCore/QTemporaryFile>
#include <QtCore/QFuture>
#include <QtGui/QErrorMessage>
using namespace Git;
using namespace Git::Internal;
const char* const kGitCommand = "git";
const char* const kGitDirectoryC = ".git";
const char* const kBranchIndicatorC = "# On branch";
static inline QString msgServerFailure()
{
return GitClient::tr(
"Note that the git plugin for QtCreator is not able to interact with the server "
"so far. Thus, manual ssh-identification etc. will not work.");
}
inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property, const QString &entry)
{
foreach (Core::IEditor *ed, core->editorManager()->openedEditors())
if (ed->property(property).toString() == entry)
return ed;
return 0;
}
GitClient::GitClient(GitPlugin* plugin, Core::ICore *core) :
m_msgWait(tr("Waiting for data...")),
m_plugin(plugin),
m_core(core)
{
}
GitClient::~GitClient()
{
}
bool GitClient::vcsOpen(const QString &fileName)
{
return m_plugin->vcsOpen(fileName);
}
QString GitClient::findRepositoryForFile(const QString &fileName)
{
const QString gitDirectory = QLatin1String(kGitDirectoryC);
const QFileInfo info(fileName);
QDir dir = info.absoluteDir();
do {
if (dir.entryList(QDir::AllDirs|QDir::Hidden).contains(gitDirectory))
return dir.absolutePath();
} while (dir.cdUp());
return QString();
}
QString GitClient::findRepositoryForDirectory(const QString &dir)
{
const QString gitDirectory = QLatin1String(kGitDirectoryC);
QDir directory(dir);
do {
if (directory.entryList(QDir::AllDirs|QDir::Hidden).contains(gitDirectory))
return directory.absolutePath();
} while (directory.cdUp());
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
* already open). */
VCSBase::VCSBaseEditor
*GitClient::createVCSEditor(const QString &kind,
QString title,
// Source file or directory
const QString &source,
bool setSourceCodec,
// Dynamic property and value to identify that editor
const char *registerDynamicProperty,
const QString &dynamicPropertyValue) const
{
VCSBase::VCSBaseEditor *rc = 0;
Core::IEditor* outputEditor = locateEditor(m_core, registerDynamicProperty, dynamicPropertyValue);
if (outputEditor) {
// Exists already
outputEditor->createNew(m_msgWait);
rc = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor);
Q_ASSERT(rc);
m_core->editorManager()->setCurrentEditor(outputEditor);
} else {
// Create new, set wait message, set up with source and codec
outputEditor = m_core->editorManager()->newFile(kind, &title, m_msgWait);
outputEditor->setProperty(registerDynamicProperty, dynamicPropertyValue);
rc = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor);
Q_ASSERT(rc);
rc->setSource(source);
if (setSourceCodec)
rc->setCodec(VCSBase::VCSBaseEditor::getCodec(m_core, source));
}
return rc;
}
void GitClient::diff(const QString &workingDirectory, const QStringList &fileNames)
{
if (Git::Constants::debug)
qDebug() << "diff" << workingDirectory << fileNames;
QStringList arguments;
arguments << QLatin1String("diff") << fileNames;
const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND);
const QString title = tr("Git Diff");
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, workingDirectory, true, "originalFileName", workingDirectory);
executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
}
void GitClient::diff(const QString &workingDirectory, const QString &fileName)
{
if (Git::Constants::debug)
qDebug() << "diff" << workingDirectory << fileName;
QStringList arguments;
arguments << QLatin1String("diff");
if (!fileName.isEmpty())
arguments << fileName;
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);
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "originalFileName", sourceFile);
executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
}
void GitClient::status(const QString &workingDirectory)
{
executeGit(workingDirectory, QStringList(QLatin1String("status")), m_plugin->m_outputWindow, 0,true);
}
void GitClient::log(const QString &workingDirectory, const QString &fileName)
{
if (Git::Constants::debug)
qDebug() << "log" << workingDirectory << fileName;
QStringList arguments;
int logCount = 10;
if (m_plugin->m_settingsPage && m_plugin->m_settingsPage->logCount() > 0)
logCount = m_plugin->m_settingsPage->logCount();
arguments << QLatin1String("log") << QLatin1String("-n")
<< QString::number(logCount);
if (!fileName.isEmpty())
arguments << fileName;
const QString title = tr("Git Log %1").arg(fileName);
const QString kind = QLatin1String(Git::Constants::GIT_LOG_EDITOR_KIND);
const QString sourceFile = source(workingDirectory, fileName);
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, false, "logFileName", sourceFile);
executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
}
void GitClient::show(const QString &source, const QString &id)
{
if (Git::Constants::debug)
qDebug() << "show" << source << id;
QStringList arguments(QLatin1String("show"));
arguments << id;
const QString title = tr("Git Show %1").arg(id);
const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND);
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, source, true, "show", id);
const QFileInfo sourceFi(source);
const QString workDir = sourceFi.isDir() ? sourceFi.absoluteFilePath() : sourceFi.absolutePath();
executeGit(workDir, arguments, m_plugin->m_outputWindow, editor);
}
void GitClient::blame(const QString &workingDirectory, const QString &fileName)
{
if (Git::Constants::debug)
qDebug() << "blame" << workingDirectory << fileName;
QStringList arguments(QLatin1String("blame"));
arguments << 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);
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "blameFileName", sourceFile);
executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
}
void GitClient::checkout(const QString &workingDirectory, const QString &fileName)
{
// Passing an empty argument as the file name is very dangereous, since this makes
// git checkout apply to all files. Almost looks like a bug in git.
if (fileName.isEmpty())
return;
QStringList arguments;
arguments << QLatin1String("checkout") << QLatin1String("HEAD") << QLatin1String("--")
<< fileName;
executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true);
}
void GitClient::hardReset(const QString &workingDirectory, const QString &commit)
{
QStringList arguments;
arguments << QLatin1String("reset") << QLatin1String("--hard");
if (!commit.isEmpty())
arguments << commit;
executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true);
}
void GitClient::addFile(const QString &workingDirectory, const QString &fileName)
{
QStringList arguments;
arguments << QLatin1String("add") << fileName;
executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true);
}
bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringList &files)
{
QByteArray outputText;
QByteArray errorText;
QStringList arguments;
arguments << "add" << files;
const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText);
if (!rc) {
const QString errorMessage = tr("Unable to add %n file(s) to %1: %2", 0, files.size()).
arg(workingDirectory, QString::fromLocal8Bit(errorText));
m_plugin->m_outputWindow->append(errorMessage);
m_plugin->m_outputWindow->popup(false);
}
return rc;
}
void GitClient::executeGit(const QString &workingDirectory, const QStringList &arguments,
GitOutputWindow *outputWindow, VCSBase::VCSBaseEditor* editor,
bool outputToWindow)
{
if (Git::Constants::debug)
qDebug() << "executeGit" << workingDirectory << arguments << editor;
outputWindow->clearContents();
QProcess process;
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
if (m_plugin->m_settingsPage && !m_plugin->m_settingsPage->adoptEnvironment())
environment.set(QLatin1String("PATH"), m_plugin->m_settingsPage->path());
GitCommand* command = new GitCommand();
if (outputToWindow) {
Q_ASSERT(outputWindow);
connect(command, SIGNAL(outputText(QString)), outputWindow, SLOT(append(QString)));
connect(command, SIGNAL(outputData(QByteArray)), outputWindow, SLOT(appendData(QByteArray)));
} else {
Q_ASSERT(editor);
connect(command, SIGNAL(outputText(QString)), editor, SLOT(setPlainText(QString)));
connect(command, SIGNAL(outputData(QByteArray)), editor, SLOT(setPlainTextData(QByteArray)));
}
if (outputWindow)
connect(command, SIGNAL(errorText(QString)), outputWindow, SLOT(append(QString)));
command->execute(arguments, workingDirectory, environment);
}
bool GitClient::synchronousGit(const QString &workingDirectory
, const QStringList &arguments
, QByteArray* outputText
, QByteArray* errorText)
{
if (Git::Constants::debug)
qDebug() << "synchronousGit" << workingDirectory << arguments;
QProcess process;
process.setWorkingDirectory(workingDirectory);
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
if (m_plugin->m_settingsPage && !m_plugin->m_settingsPage->adoptEnvironment())
environment.set(QLatin1String("PATH"), m_plugin->m_settingsPage->path());
process.setEnvironment(environment.toStringList());
process.start(QLatin1String(kGitCommand), arguments);
if (!process.waitForFinished()) {
if (errorText)
*errorText = "Error: Git timed out";
return false;
}
if (outputText)
*outputText = process.readAllStandardOutput();
if (errorText)
*errorText = process.readAllStandardError();
if (Git::Constants::debug)
qDebug() << "synchronousGit ex=" << process.exitCode();
return process.exitCode() == 0;
}
/* Parse a git status file list:
* \code
# Changes to be committed:
#<tab>modified:<blanks>git.pro
# Changed but not updated:
#<tab>modified:<blanks>git.pro
# Untracked files:
#<tab>modified:<blanks>git.pro
\endcode
*/
static bool parseFiles(const QStringList &lines, CommitData *d)
{
enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles };
const QString branchIndicator = QLatin1String(kBranchIndicatorC);
const QString commitIndicator = QLatin1String("# Changes to be committed:");
const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:");
const QString untrackedIndicator = QLatin1String("# Untracked files:");
State s = None;
const QRegExp filesPattern(QLatin1String("#\\t[^:]+:\\s+[^ ]+"));
Q_ASSERT(filesPattern.isValid());
const QStringList::const_iterator cend = lines.constEnd();
for (QStringList::const_iterator it = lines.constBegin(); it != cend; ++it) {
const QString line = *it;
if (line.startsWith(branchIndicator)) {
d->panelInfo.branch = line.mid(branchIndicator.size() + 1);
} else {
if (line.startsWith(commitIndicator)) {
s = CommitFiles;
} else {
if (line.startsWith(notUpdatedIndicator)) {
s = NotUpdatedFiles;
} else {
if (line.startsWith(untrackedIndicator)) {
s = UntrackedFiles;
} else {
if (filesPattern.exactMatch(line)) {
const QString fileSpec = line.mid(2).simplified();
switch (s) {
case CommitFiles:
d->commitFiles.push_back(fileSpec);
break;
case NotUpdatedFiles:
d->notUpdatedFiles.push_back(fileSpec);
break;
case UntrackedFiles:
d->untrackedFiles.push_back(fileSpec);
break;
case None:
break;
}
}
}
}
}
}
}
return !d->commitFiles.empty() || !d->notUpdatedFiles.empty() || !d->untrackedFiles.empty();
}
bool GitClient::getCommitData(const QString &workingDirectory,
QString *commitTemplate,
CommitData *d,
QString *errorMessage)
{
d->clear();
// Find repo
const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
if (repoDirectory.isEmpty()) {
*errorMessage = tr("Unable to determine the repository for %1.").arg(workingDirectory);
return false;
}
d->panelInfo.repository = repoDirectory;
QDir gitDir(repoDirectory);
if (!gitDir.cd(QLatin1String(kGitDirectoryC))) {
*errorMessage = tr("The repository %1 is not initialized yet.").arg(repoDirectory);
return false;
}
// Read description
const QString descriptionFile = gitDir.absoluteFilePath(QLatin1String("description"));
if (QFileInfo(descriptionFile).isFile()) {
QFile file(descriptionFile);
if (file.open(QIODevice::ReadOnly|QIODevice::Text))
d->panelInfo.description = QString::fromLocal8Bit(file.readAll()).trimmed();
}
// Run status. Note that it has exitcode 1 if there are no added files.
QByteArray outputText;
QByteArray errorText;
const bool statusRc = synchronousGit(workingDirectory, QStringList(QLatin1String("status")), &outputText, &errorText);
if (!statusRc) {
// Something fatal
if (!outputText.contains(kBranchIndicatorC)) {
*errorMessage = tr("Unable to obtain the project status: %1").arg(QString::fromLocal8Bit(errorText));
return false;
}
// All unchanged
if (outputText.contains("nothing to commit")) {
*errorMessage = tr("There are no modified files.");
return false;
}
}
// Output looks like:
// # On branch [branchname]
// # Changes to be committed:
// # (use "git reset HEAD <file>..." to unstage)
// #
// # modified: somefile.cpp
// # new File: somenew.h
// #
// # Changed but not updated:
// # (use "git add <file>..." to update what will be committed)
// #
// # modified: someother.cpp
// #
// # Untracked files:
// # (use "git add <file>..." to include in what will be committed)
// #
// # list of files...
const QStringList lines = QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r')).split(QLatin1Char('\n'));
if (!parseFiles(lines, d)) {
*errorMessage = tr("Unable to parse the file output.");
return false;
}
d->panelData.author = readConfigValue(workingDirectory, QLatin1String("user.name"));
d->panelData.email = readConfigValue(workingDirectory, QLatin1String("user.email"));
// Get the commit template
const QString templateFilename = readConfigValue(workingDirectory, QLatin1String("commit.template"));
if (!templateFilename.isEmpty()) {
QFile templateFile(templateFilename);
if (templateFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
*commitTemplate = QString::fromLocal8Bit(templateFile.readAll());
} else {
qWarning("Unable to read commit template %s: %s",
qPrintable(templateFilename),
qPrintable(templateFile.errorString()));
}
}
return true;
}
bool GitClient::addAndCommit(const QString &workingDirectory,
const GitSubmitEditorPanelData &data,
const QString &messageFile,
const QStringList &files)
{
// Re-add all to make sure we have the latest changes
if (!synchronousAdd(workingDirectory, files))
return false;
// Do the final commit
QStringList args;
args << QLatin1String("commit")
<< QLatin1String("-F") << QDir::toNativeSeparators(messageFile)
<< QLatin1String("--author") << data.authorString();
QByteArray outputText;
QByteArray errorText;
const bool rc = synchronousGit(workingDirectory, args, &outputText, &errorText);
const QString message = rc ?
tr("Committed %n file(s).", 0, files.size()) :
tr("Unable to commit %n file(s): %1", 0, files.size()).arg(QString::fromLocal8Bit(errorText));
m_plugin->m_outputWindow->append(message);
m_plugin->m_outputWindow->popup(false);
return rc;
}
void GitClient::pull(const QString &workingDirectory)
{
executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->m_outputWindow, 0,true);
}
void GitClient::push(const QString &workingDirectory)
{
executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->m_outputWindow, 0,true);
}
QString GitClient::readConfig(const QString &workingDirectory, const QStringList &configVar)
{
QStringList arguments;
arguments << QLatin1String("config") << configVar;
QByteArray outputText;
if (synchronousGit(workingDirectory, arguments, &outputText))
return outputText;
return QString();
}
// Read a single-line config value, return trimmed
QString GitClient::readConfigValue(const QString &workingDirectory, const QString &configVar)
{
return readConfig(workingDirectory, QStringList(configVar)).remove(QLatin1Char('\n'));
}
GitCommand::GitCommand()
{
}
GitCommand::~GitCommand()
{
}
void GitCommand::execute(const QStringList &arguments
, const QString &workingDirectory
, const ProjectExplorer::Environment &environment)
{
if (Git::Constants::debug)
qDebug() << "GitCommand::execute" << workingDirectory << arguments;
// For some reason QtConcurrent::run() only works on this
QFuture<void> task = QtConcurrent::run(this, &GitCommand::run
, arguments
, workingDirectory
, environment);
QString taskName = QLatin1String("Git ") + arguments[0];
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
core->progressManager()->addTask(task, taskName
, QLatin1String("Git.action")
, Core::ProgressManagerInterface::CloseOnSuccess);
}
void GitCommand::run(const QStringList &arguments
, const QString &workingDirectory
, const ProjectExplorer::Environment &environment)
{
if (Git::Constants::debug)
qDebug() << "GitCommand::run" << workingDirectory << arguments;
QProcess process;
if (!workingDirectory.isEmpty())
process.setWorkingDirectory(workingDirectory);
ProjectExplorer::Environment env = environment;
if (env.toStringList().isEmpty())
env = ProjectExplorer::Environment::systemEnvironment();
process.setEnvironment(env.toStringList());
process.start(QLatin1String(kGitCommand), arguments);
if (!process.waitForFinished()) {
emit errorText(QLatin1String("Error: Git timed out"));
return;
}
const QByteArray output = process.readAllStandardOutput();
if (output.isEmpty()) {
if (arguments.at(0) == QLatin1String("diff"))
emit outputText(tr("The file does not differ from HEAD"));
} else {
emit outputData(output);
}
const QByteArray error = process.readAllStandardError();
if (!error.isEmpty())
emit errorText(QString::fromLocal8Bit(error));
// As it is used asynchronously, we need to delete ourselves
this->deleteLater();
}

168
src/plugins/git/gitclient.h Normal file
View File

@@ -0,0 +1,168 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GITCLIENT_H
#define GITCLIENT_H
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/editormanager/ieditor.h>
#include <projectexplorer/environment.h>
#include <QtCore/QString>
#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
class QErrorMessage;
QT_END_NAMESPACE
namespace Core {
class ICore;
}
namespace VCSBase {
class VCSBaseEditor;
}
namespace Git {
namespace Internal {
class GitPlugin;
class GitOutputWindow;
class GitCommand;
struct CommitData;
struct GitSubmitEditorPanelData;
class GitClient : public Core::IVersionControl
{
Q_OBJECT
public:
explicit GitClient(GitPlugin *plugin, Core::ICore *core);
~GitClient();
bool vcsOpen(const QString &fileName);
bool vcsAdd(const QString&) {return false;}
bool vcsDelete(const QString&) {return false;}
bool managesDirectory(const QString&) const {return false;}
QString findTopLevelForDirectory(const QString&) const {return QString();}
static QString findRepositoryForFile(const QString &fileName);
static QString findRepositoryForDirectory(const QString &dir);
void diff(const QString &workingDirectory,
const QString &fileName);
void diff(const QString &workingDirectory,
const QStringList &fileNames);
void status(const QString &workingDirectory);
void log(const QString &workingDirectory
, const QString &fileName);
void blame(const QString &workingDirectory
, const QString &fileName);
void showCommit(const QString &workingDirectory
, const QString &commit);
void checkout(const QString &workingDirectory
, const QString &file);
void hardReset(const QString &workingDirectory
, const QString &commit);
void addFile(const QString &workingDirectory
, const QString &fileName);
bool synchronousAdd(const QString &workingDirectory,
const QStringList &files);
void pull(const QString &workingDirectory);
void push(const QString &workingDirectory);
QString readConfig(const QString &workingDirectory
, const QStringList &configVar);
QString readConfigValue(const QString &workingDirectory,
const QString &configVar);
bool getCommitData(const QString &workingDirectory,
QString *commitTemplate,
CommitData *d,
QString *errorMessage);
bool addAndCommit(const QString &workingDirectory,
const GitSubmitEditorPanelData &data,
const QString &messageFile,
const QStringList &files);
public slots:
void show(const QString &source, const QString &id);
private:
VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind,
QString title,
const QString &source,
bool setSourceCodec,
const char *registerDynamicProperty,
const QString &dynamicPropertyValue) const;
void executeGit(const QString &workingDirectory
, const QStringList &arguments
, GitOutputWindow *outputWindow
, VCSBase::VCSBaseEditor* editor = 0
, bool outputToWindow = false);
bool synchronousGit(const QString &workingDirectory
, const QStringList &arguments
, QByteArray* outputText = 0
, QByteArray* errorText = 0);
const QString m_msgWait;
GitPlugin *m_plugin;
Core::ICore *m_core;
};
class GitCommand : public QObject
{
Q_OBJECT
public:
GitCommand();
~GitCommand();
void execute(const QStringList &arguments
, const QString &workingDirectory
, const ProjectExplorer::Environment &environment);
void run(const QStringList &arguments
, const QString &workingDirectory
, const ProjectExplorer::Environment &environment);
Q_SIGNALS:
void outputData(const QByteArray&);
void outputText(const QString&);
void errorText(const QString&);
};
}
}
#endif // GITCLIENT_H

View File

@@ -0,0 +1,58 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GIT_CONSTANTS_H
#define GIT_CONSTANTS_H
namespace Git {
namespace Constants {
const char * const GIT_COMMAND_LOG_EDITOR_KIND = "Git Command Log Editor";
const char * const GIT_LOG_EDITOR_KIND = "Git File Log Editor";
const char * const GIT_BLAME_EDITOR_KIND = "Git Annotation Editor";
const char * const GIT_DIFF_EDITOR_KIND = "Git Diff Editor";
const char * const C_GITSUBMITEDITOR = "Git Submit Editor";
const char * const GITSUBMITEDITOR_KIND = "Git Submit Editor";
const char * const SUBMIT_CURRENT = "Nokia.Git.SubmitCurrentLog";
const char * const DIFF_SELECTED = "Nokia.Git.DiffSelectedFilesInLog";
const char * const SUBMIT_MIMETYPE = "application/vnd.nokia.text.git.submit";
// TODO: For the moment, trust p4 is loaded...
const char * const ICON_SUBMIT = ":/trolltech.perforce/images/submit.png";
const char * const ICON_DIFF = ":/trolltech.perforce/images/diff.png";
const char * const DIFF_FILE_INDICATOR = "--- ";
enum { debug = 0 };
}
}
#endif // GIT_CONSTANTS_H

View File

@@ -0,0 +1,145 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "giteditor.h"
#include "annotationhighlighter.h"
#include "gitconstants.h"
#include "gitplugin.h"
#include "gitclient.h"
#include <vcsbase/diffhighlighter.h>
#include <coreplugin/editormanager/editormanager.h>
#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>
#include <QtCore/QSet>
#include <QtCore/QRegExp>
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtGui/QTextEdit>
#include <QtGui/QTextCursor>
#define CHANGE_PATTERN_8C "[a-f0-9]{8,8}"
#define CHANGE_PATTERN_40C "[a-f0-9]{40,40}"
namespace Git {
namespace Internal {
// ------------ GitEditor
GitEditor::GitEditor(const VCSBase::VCSBaseEditorParameters *type,
QWidget *parent) :
VCSBase::VCSBaseEditor(type, parent),
m_changeNumberPattern8(QLatin1String(CHANGE_PATTERN_8C)),
m_changeNumberPattern40(QLatin1String(CHANGE_PATTERN_40C))
{
Q_ASSERT(m_changeNumberPattern8.isValid());
Q_ASSERT(m_changeNumberPattern40.isValid());
if (Git::Constants::debug)
qDebug() << "GitEditor::GitEditor" << type->type << type->kind;
}
QSet<QString> GitEditor::annotationChanges() const
{
QSet<QString> changes;
const QString txt = toPlainText();
if (txt.isEmpty())
return changes;
// Hunt for first change number in annotation: "<change>:"
QRegExp r(QLatin1String("^("CHANGE_PATTERN_8C") "));
Q_ASSERT(r.isValid());
if (r.indexIn(txt) != -1) {
changes.insert(r.cap(1));
r.setPattern(QLatin1String("\n("CHANGE_PATTERN_8C") "));
Q_ASSERT(r.isValid());
int pos = 0;
while ((pos = r.indexIn(txt, pos)) != -1) {
pos += r.matchedLength();
changes.insert(r.cap(1));
}
}
if (Git::Constants::debug)
qDebug() << "GitEditor::annotationChanges() returns #" << changes.size();
return changes;
}
QString GitEditor::changeUnderCursor(const QTextCursor &c) const
{
QTextCursor cursor = c;
// Any number is regarded as change number.
cursor.select(QTextCursor::WordUnderCursor);
if (!cursor.hasSelection())
return QString();
const QString change = cursor.selectedText();
if (Git::Constants::debug > 1)
qDebug() << "GitEditor:::changeUnderCursor:" << change;
if (m_changeNumberPattern8.exactMatch(change))
return change;
if (m_changeNumberPattern40.exactMatch(change))
return change;
return QString();
}
VCSBase::DiffHighlighter *GitEditor::createDiffHighlighter() const
{
const QRegExp filePattern(QLatin1String("^[-+][-+][-+] [ab].*"));
return new VCSBase::DiffHighlighter(filePattern);
}
VCSBase::BaseAnnotationHighlighter *GitEditor::createAnnotationHighlighter(const QSet<QString> &changes) const
{
return new GitAnnotationHighlighter(changes);
}
QString GitEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
{
QString errorMessage;
// Check for "+++ b/src/plugins/git/giteditor.cpp" (blame and diff)
// Go back chunks.
const QString newFileIndicator = QLatin1String("+++ b/");
for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) {
QString diffFileName = block.text();
if (diffFileName.startsWith(newFileIndicator)) {
diffFileName.remove(0, newFileIndicator.size());
const QString fileOrDir = source();
const QString repo = QFileInfo(fileOrDir).isDir() ?
GitClient::findRepositoryForDirectory(fileOrDir) : GitClient::findRepositoryForFile(fileOrDir);
const QString absPath = QDir(repo).absoluteFilePath(diffFileName);
if (Git::Constants::debug)
qDebug() << "fileNameFromDiffSpecification" << repo << diffFileName << absPath;
return absPath;
}
}
return QString();
}
}
}

View File

@@ -0,0 +1,68 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GITEDITOR_H
#define GITEDITOR_H
#include <vcsbase/vcsbaseeditor.h>
#include <QtCore/QRegExp>
namespace Git {
namespace Internal {
class GitPlugin;
class GitEditor : public VCSBase::VCSBaseEditor
{
Q_OBJECT
public:
explicit GitEditor(const VCSBase::VCSBaseEditorParameters *type,
QWidget *parent);
private:
virtual QSet<QString> annotationChanges() const;
virtual QString changeUnderCursor(const QTextCursor &) const;
virtual VCSBase::DiffHighlighter *createDiffHighlighter() const;
virtual VCSBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes) const;
virtual QString fileNameFromDiffSpecification(const QTextBlock &diffFileName) const;
const QRegExp m_changeNumberPattern8;
const QRegExp m_changeNumberPattern40;
GitPlugin *m_plugin;
};
} // namespace Git
} // namespace Internal
#endif // GITEDITOR_H

View File

@@ -0,0 +1,122 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gitoutputwindow.h"
#include <QtCore/QTextCodec>
#include <QtGui/QKeyEvent>
#include <QtGui/QMouseEvent>
#include <QtGui/QMenu>
#include <QtGui/QAction>
#include <QtGui/QListWidget>
using namespace Git::Internal;
GitOutputWindow::GitOutputWindow()
: Core::IOutputPane()
{
m_outputListWidget = new QListWidget;
m_outputListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_outputListWidget->setFrameStyle(QFrame::NoFrame);
m_outputListWidget->setWindowTitle(tr("Git Output"));
}
GitOutputWindow::~GitOutputWindow()
{
delete m_outputListWidget;
}
QWidget *GitOutputWindow::outputWidget(QWidget *parent)
{
m_outputListWidget->setParent(parent);
return m_outputListWidget;
}
QString GitOutputWindow::name() const
{
return tr("Git");
}
void GitOutputWindow::clearContents()
{
m_outputListWidget->clear();
}
void GitOutputWindow::visibilityChanged(bool b)
{
if (b)
m_outputListWidget->setFocus();
}
bool GitOutputWindow::hasFocus()
{
return m_outputListWidget->hasFocus();
}
bool GitOutputWindow::canFocus()
{
return false;
}
void GitOutputWindow::setFocus()
{
}
void GitOutputWindow::setText(const QString &text)
{
clearContents();
append(text);
}
void GitOutputWindow::append(const QString &text)
{
const QStringList lines = text.split(QLatin1Char('\n'));
foreach (const QString &s, lines)
m_outputListWidget->addItem(s);
popup();
}
void GitOutputWindow::setData(const QByteArray &data)
{
setText(QTextCodec::codecForLocale()->toUnicode(data));
}
void GitOutputWindow::appendData(const QByteArray &data)
{
append(QTextCodec::codecForLocale()->toUnicode(data));
}
int GitOutputWindow::priorityInStatusBar() const
{
return -1;
}

View File

@@ -0,0 +1,79 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GITOUTPUTWINDOW_H
#define GITOUTPUTWINDOW_H
#include <coreplugin/ioutputpane.h>
#include <QtGui/QAction>
#include <QtGui/QListWidget>
#include <QtGui/QListWidgetItem>
namespace Git {
namespace Internal {
class GitOutputWindow : public Core::IOutputPane
{
Q_OBJECT
public:
GitOutputWindow();
~GitOutputWindow();
QWidget *outputWidget(QWidget *parent);
QList<QWidget*> toolBarWidgets(void) const { return QList<QWidget *>(); }
QString name() const;
int priorityInStatusBar() const;
void clearContents();
void visibilityChanged(bool visible);
bool canFocus();
bool hasFocus();
void setFocus();
public slots:
void setText(const QString &text);
void append(const QString &text);
void setData(const QByteArray &data);
void appendData(const QByteArray &data);
private:
QListWidget *m_outputListWidget;
};
} // namespace Internal
} // namespace Git
#endif

View File

@@ -0,0 +1,717 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gitplugin.h"
#include "gitclient.h"
#include "giteditor.h"
#include "gitconstants.h"
#include "changeselectiondialog.h"
#include "gitsubmiteditor.h"
#include "commitdata.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <coreplugin/editormanager/editormanager.h>
#include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/basevcssubmiteditorfactory.h>
#include <QtCore/qplugin.h>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtCore/QTemporaryFile>
#include <QtCore/QDir>
#include <QtGui/QAction>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
#include <QtGui/QMainWindow>
#include <QtGui/QFileDialog>
static const VCSBase::VCSBaseEditorParameters editorParameters[] = {
{
VCSBase::RegularCommandOutput,
Git::Constants::GIT_COMMAND_LOG_EDITOR_KIND,
Core::Constants::C_GLOBAL,
"application/vnd.nokia.text.scs_git_commandlog",
"gitlog"},
{ VCSBase::LogOutput,
Git::Constants::GIT_LOG_EDITOR_KIND,
Core::Constants::C_GLOBAL,
"application/vnd.nokia.text.scs_git_filelog",
"gitfilelog"},
{ VCSBase::AnnotateOutput,
Git::Constants::GIT_BLAME_EDITOR_KIND,
Core::Constants::C_GLOBAL,
"application/vnd.nokia.text.scs_git_annotation",
"gitsannotate"},
{ VCSBase::DiffOutput,
Git::Constants::GIT_DIFF_EDITOR_KIND,
Core::Constants::C_GLOBAL,
"text/x-patch","diff"}
};
// Utility to find a parameter set by type
static inline const VCSBase::VCSBaseEditorParameters *findType(int ie)
{
const VCSBase::EditorContentType et = static_cast<VCSBase::EditorContentType>(ie);
return VCSBase::VCSBaseEditor::findType(editorParameters, sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters), et);
}
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() :
m_core(0),
m_diffAction(0),
m_diffProjectAction(0),
m_statusAction(0),
m_statusProjectAction(0),
m_logAction(0),
m_blameAction(0),
m_logProjectAction(0),
m_undoFileAction(0),
m_undoProjectAction(0),
m_showAction(0),
m_addAction(0),
m_commitAction(0),
m_pullAction(0),
m_pushAction(0),
m_submitCurrentAction(0),
m_diffSelectedFilesAction(0),
m_undoAction(0),
m_redoAction(0),
m_projectExplorer(0),
m_gitClient(0),
m_outputWindow(0),
m_changeSelectionDialog(0),
m_settingsPage(0),
m_coreListener(0),
m_submitEditorFactory(0),
m_changeTmpFile(0)
{
Q_ASSERT(m_instance == 0);
m_instance = this;
}
GitPlugin::~GitPlugin()
{
if (m_outputWindow) {
removeObject(m_outputWindow);
delete m_outputWindow;
m_outputWindow = 0;
}
if (m_settingsPage) {
removeObject(m_settingsPage);
delete m_settingsPage;
m_settingsPage = 0;
}
if (!m_editorFactories.empty()) {
foreach(Core::IEditorFactory* pf, m_editorFactories)
removeObject(pf);
qDeleteAll(m_editorFactories);
}
if (m_coreListener) {
removeObject(m_coreListener);
delete m_coreListener;
m_coreListener = 0;
}
if (m_submitEditorFactory) {
removeObject(m_submitEditorFactory);
m_submitEditorFactory = 0;
}
cleanChangeTmpFile();
delete m_gitClient;
m_instance = 0;
}
void GitPlugin::cleanChangeTmpFile()
{
if (m_changeTmpFile) {
delete m_changeTmpFile;
m_changeTmpFile = 0;
}
}
GitPlugin *GitPlugin::instance()
{
return m_instance;
}
static const VCSBase::VCSBaseSubmitEditorParameters submitParameters = {
Git::Constants::SUBMIT_MIMETYPE,
Git::Constants::GITSUBMITEDITOR_KIND,
Git::Constants::C_GITSUBMITEDITOR,
Core::Constants::UNDO,
Core::Constants::REDO,
Git::Constants::SUBMIT_CURRENT,
Git::Constants::DIFF_SELECTED
};
bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
{
typedef VCSBase::VCSEditorFactory<GitEditor> GitEditorFactory;
typedef VCSBase::VCSSubmitEditorFactory<GitSubmitEditor> GitSubmitEditorFactory;
Q_UNUSED(arguments);
Q_UNUSED(error_message);
m_core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
m_gitClient = new GitClient(this, m_core);
// Create the globalcontext list to register actions accordingly
QList<int> globalcontext;
globalcontext << m_core->uniqueIDManager()->
uniqueIdentifier(Core::Constants::C_GLOBAL);
// Create the output Window
m_outputWindow = new GitOutputWindow();
addObject(m_outputWindow);
// Create the settings Page
m_settingsPage = new SettingsPage();
addObject(m_settingsPage);
static const char *describeSlot = SLOT(show(QString,QString));
const int editorCount = sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters);
for (int i = 0; i < editorCount; i++) {
m_editorFactories.push_back(new GitEditorFactory(editorParameters + i, m_core, m_gitClient, describeSlot));
addObject(m_editorFactories.back());
}
m_coreListener = new CoreListener(this);
addObject(m_coreListener);
m_submitEditorFactory = new GitSubmitEditorFactory(&submitParameters);
addObject(m_submitEditorFactory);
//register actions
Core::ActionManagerInterface *actionManager = m_core->actionManager();
Core::IActionContainer *toolsContainer =
actionManager->actionContainer(Core::Constants::M_TOOLS);
Core::IActionContainer *gitContainer =
actionManager->createMenu(QLatin1String("Git"));
gitContainer->menu()->setTitle(tr("&Git"));
toolsContainer->addMenu(gitContainer);
Core::ICommand *command;
QAction *tmpaction;
m_diffAction = new QAction(tr("Diff current file"), this);
command = actionManager->registerAction(m_diffAction, "Git.Diff", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+D")));
connect(m_diffAction, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
gitContainer->addAction(command);
m_statusAction = new QAction(tr("File Status"), this);
command = actionManager->registerAction(m_statusAction, "Git.Status", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+S")));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_statusAction, SIGNAL(triggered()), this, SLOT(statusFile()));
gitContainer->addAction(command);
m_logAction = new QAction(tr("Log File"), this);
command = actionManager->registerAction(m_logAction, "Git.Log", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+L")));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_logAction, SIGNAL(triggered()), this, SLOT(logFile()));
gitContainer->addAction(command);
m_blameAction = new QAction(tr("Blame"), this);
command = actionManager->registerAction(m_blameAction, "Git.Blame", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+B")));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_blameAction, SIGNAL(triggered()), this, SLOT(blameFile()));
gitContainer->addAction(command);
m_undoFileAction = new QAction(tr("Undo Changes"), this);
command = actionManager->registerAction(m_undoFileAction, "Git.Undo", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+U")));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_undoFileAction, SIGNAL(triggered()), this, SLOT(undoFileChanges()));
gitContainer->addAction(command);
m_addAction = new QAction(tr("Add File"), this);
command = actionManager->registerAction(m_addAction, "Git.Add", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+A")));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_addAction, SIGNAL(triggered()), this, SLOT(addFile()));
gitContainer->addAction(command);
tmpaction = new QAction(this);
tmpaction->setSeparator(true);
command = actionManager->registerAction(tmpaction, QLatin1String("Git.Sep.Project"), globalcontext);
gitContainer->addAction(command);
m_diffProjectAction = new QAction(tr("Diff current project"), this);
command = actionManager->registerAction(m_diffProjectAction, "Git.DiffProject", globalcontext);
command->setDefaultKeySequence(QKeySequence("Alt+G,Alt+Shift+D"));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_diffProjectAction, SIGNAL(triggered()), this, SLOT(diffCurrentProject()));
gitContainer->addAction(command);
m_statusProjectAction = new QAction(tr("Project status"), this);
command = actionManager->registerAction(m_statusProjectAction, "Git.StatusProject", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_statusProjectAction, SIGNAL(triggered()), this, SLOT(statusProject()));
gitContainer->addAction(command);
m_logProjectAction = new QAction(tr("Log project"), this);
command = actionManager->registerAction(m_logProjectAction, "Git.LogProject", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+K")));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_logProjectAction, SIGNAL(triggered()), this, SLOT(logProject()));
gitContainer->addAction(command);
m_undoProjectAction = new QAction(tr("Undo Project Changes"), this);
command = actionManager->registerAction(m_undoProjectAction, "Git.UndoProject", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_undoProjectAction, SIGNAL(triggered()), this, SLOT(undoProjectChanges()));
gitContainer->addAction(command);
tmpaction = new QAction(this);
tmpaction->setSeparator(true);
command = actionManager->registerAction(tmpaction, QLatin1String("Git.Sep.Global"), globalcontext);
gitContainer->addAction(command);
m_showAction = new QAction(tr("Show commit..."), this);
command = actionManager->registerAction(m_showAction, "Git.ShowCommit", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_showAction, SIGNAL(triggered()), this, SLOT(showCommit()));
gitContainer->addAction(command);
m_commitAction = new QAction(tr("Commit..."), this);
command = actionManager->registerAction(m_commitAction, "Git.Commit", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+C")));
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_commitAction, SIGNAL(triggered()), this, SLOT(startCommit()));
gitContainer->addAction(command);
m_pullAction = new QAction(tr("Pull"), this);
command = actionManager->registerAction(m_pullAction, "Git.Pull", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_pullAction, SIGNAL(triggered()), this, SLOT(pull()));
gitContainer->addAction(command);
m_pushAction = new QAction(tr("Push"), this);
command = actionManager->registerAction(m_pushAction, "Git.Push", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_pushAction, SIGNAL(triggered()), this, SLOT(push()));
gitContainer->addAction(command);
// Submit editor
QList<int> submitContext;
submitContext.push_back(m_core->uniqueIDManager()->uniqueIdentifier(QLatin1String(Constants::C_GITSUBMITEDITOR)));
m_submitCurrentAction = new QAction(QIcon(Constants::ICON_SUBMIT), tr("Commit"), this);
command = actionManager->registerAction(m_submitCurrentAction, Constants::SUBMIT_CURRENT, submitContext);
// TODO
connect(m_submitCurrentAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog()));
m_diffSelectedFilesAction = new QAction(QIcon(Constants::ICON_DIFF), tr("Diff Selected Files"), this);
command = actionManager->registerAction(m_diffSelectedFilesAction, Constants::DIFF_SELECTED, submitContext);
m_undoAction = new QAction(tr("&Undo"), this);
command = actionManager->registerAction(m_undoAction, Core::Constants::UNDO, submitContext);
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;
}
void GitPlugin::extensionsInitialized()
{
m_projectExplorer = ExtensionSystem::PluginManager::instance()->getObject<ProjectExplorer::ProjectExplorerPlugin>();
}
bool GitPlugin::vcsOpen(const QString &fileName)
{
Q_UNUSED(fileName);
return false;
}
void GitPlugin::submitEditorDiff(const QStringList &files)
{
if (files.empty())
return;
m_gitClient->diff(m_submitRepository, files);
}
void GitPlugin::diffCurrentFile()
{
QFileInfo fileInfo = currentFile();
QString fileName = fileInfo.fileName();
QString workingDirectory = fileInfo.absolutePath();
m_gitClient->diff(workingDirectory, fileName);
}
void GitPlugin::diffCurrentProject()
{
QString workingDirectory = getWorkingDirectory();
if (workingDirectory.isEmpty())
return;
m_gitClient->diff(workingDirectory, QString());
}
QFileInfo GitPlugin::currentFile()
{
QString fileName = m_core->fileManager()->currentFile();
QFileInfo fileInfo(fileName);
return fileInfo;
}
QString GitPlugin::getWorkingDirectory()
{
QString workingDirectory;
if (m_projectExplorer && m_projectExplorer->currentNode()) {
workingDirectory = QFileInfo(m_projectExplorer->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()) {
m_outputWindow->clearContents();
m_outputWindow->append(tr("Could not find working directory"));
m_outputWindow->popup();
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());
}
void GitPlugin::logFile()
{
const QFileInfo fileInfo = currentFile();
const QString fileName = fileInfo.fileName();
const QString workingDirectory = fileInfo.absolutePath();
m_gitClient->log(workingDirectory, fileName);
}
void GitPlugin::blameFile()
{
const QFileInfo fileInfo = currentFile();
const QString fileName = fileInfo.fileName();
const QString workingDirectory = fileInfo.absolutePath();
m_gitClient->blame(workingDirectory, fileName);
}
void GitPlugin::logProject()
{
QString workingDirectory = getWorkingDirectory();
if (workingDirectory.isEmpty())
return;
m_gitClient->log(workingDirectory, QString());
}
void GitPlugin::undoFileChanges()
{
QFileInfo fileInfo = currentFile();
QString fileName = fileInfo.fileName();
QString workingDirectory = fileInfo.absolutePath();
m_gitClient->checkout(workingDirectory, fileName);
}
void GitPlugin::undoProjectChanges()
{
QString workingDirectory = getWorkingDirectory();
if (workingDirectory.isEmpty())
return;
m_gitClient->hardReset(workingDirectory, QString());
}
void GitPlugin::addFile()
{
QFileInfo fileInfo = currentFile();
QString fileName = fileInfo.fileName();
QString workingDirectory = fileInfo.absolutePath();
m_gitClient->addFile(workingDirectory, fileName);
}
void GitPlugin::startCommit()
{
if (m_changeTmpFile) {
m_outputWindow->append(tr("Another submit is currently beeing executed."));
m_outputWindow->popup(false);
return;
}
// Find repository and get commit data
const QFileInfo currentFileInfo = currentFile();
if (!currentFileInfo.exists())
return;
const QString workingDirectory = currentFileInfo.absolutePath();
QString errorMessage, commitTemplate;
CommitData data;
if (!m_gitClient->getCommitData(workingDirectory, &commitTemplate, &data, &errorMessage)) {
m_outputWindow->append(errorMessage);
m_outputWindow->popup(false);
return;
}
m_submitRepository = data.panelInfo.repository;
if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << data << commitTemplate;
// Start new temp file with message template
QTemporaryFile *changeTmpFile = new QTemporaryFile(this);
changeTmpFile->setAutoRemove(true);
if (!changeTmpFile->open()) {
m_outputWindow->append(tr("Cannot create temporary file: %1").arg(changeTmpFile->errorString()));
delete changeTmpFile;
return;
}
m_changeTmpFile = changeTmpFile;
m_changeTmpFile->write(commitTemplate.toLocal8Bit());
m_changeTmpFile->flush();
// Keep the file alive, else it removes self and forgets
// its name
m_changeTmpFile->seek(0);
openSubmitEditor(m_changeTmpFile->fileName(), data);
}
Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const CommitData &cd)
{
Core::IEditor *editor = m_core->editorManager()->openEditor(fileName, QLatin1String(Constants::GITSUBMITEDITOR_KIND));
if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << fileName << editor;
m_core->editorManager()->ensureEditorManagerVisible();
GitSubmitEditor *submitEditor = qobject_cast<GitSubmitEditor*>(editor);
Q_ASSERT(submitEditor);
// The actions are for some reason enabled by the context switching
// mechanism. Disable them correctly.
m_submitCurrentAction->setEnabled(!cd.commitFiles.empty());
m_diffSelectedFilesAction->setEnabled(false);
m_undoAction->setEnabled(false);
m_redoAction->setEnabled(false);
submitEditor->setCommitData(cd);
connect(submitEditor, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(submitEditorDiff(QStringList)));
return editor;
}
void GitPlugin::submitCurrentLog()
{
// Close the submit editor
QList<Core::IEditor*> editors;
editors.push_back(m_core->editorManager()->currentEditor());
m_core->editorManager()->closeEditors(editors);
}
bool GitPlugin::editorAboutToClose(Core::IEditor *iEditor)
{
// Closing a submit editor?
if (!m_changeTmpFile || !iEditor || qstrcmp(iEditor->kind(), Constants::GITSUBMITEDITOR_KIND))
return true;
Core::IFile *fileIFace = iEditor->file();
const GitSubmitEditor *editor = qobject_cast<GitSubmitEditor *>(iEditor);
if (!fileIFace || !editor)
return true;
// Submit editor closing. Make it write out the commit message
// and retrieve files
const QFileInfo editorFile(fileIFace->fileName());
const QFileInfo changeFile(m_changeTmpFile->fileName());
// Paranoia!
if (editorFile.absoluteFilePath() != changeFile.absoluteFilePath())
return true;
// Prompt user.
const QMessageBox::StandardButton answer = QMessageBox::question(m_core->mainWindow(), tr("Closing git editor"), tr("Do you want to commit the change?"),
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::Yes);
switch (answer) {
case QMessageBox::Cancel:
return false; // Keep editing and change file
case QMessageBox::No:
cleanChangeTmpFile();
return true; // Cancel all
default:
break;
}
// Go ahead!
const QStringList fileList = editor->checkedFiles();
if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << fileList;
if (!fileList.empty()) {
// get message & commit
m_core->fileManager()->blockFileChange(fileIFace);
fileIFace->save();
m_core->fileManager()->unblockFileChange(fileIFace);
m_gitClient->addAndCommit(m_submitRepository,
editor->panelData(),
m_changeTmpFile->fileName(),
fileList);
}
cleanChangeTmpFile();
return true;
}
void GitPlugin::pull()
{
QString workingDirectory = getWorkingDirectory();
if (workingDirectory.isEmpty())
return;
m_gitClient->pull(workingDirectory);
}
void GitPlugin::push()
{
QString workingDirectory = getWorkingDirectory();
if (workingDirectory.isEmpty())
return;
m_gitClient->push(workingDirectory);
}
void GitPlugin::updateActions()
{
QFileInfo current = currentFile();
const QString fileName = current.fileName();
const QString currentDirectory = getWorkingDirectory();
QString repository = m_gitClient->findRepositoryForFile(current.absoluteFilePath());
// First check for file commands and if the current file is inside
// a Git-repository
m_diffAction->setText(tr("Diff %1").arg(fileName));
m_statusAction->setText(tr("Status related to %1").arg(fileName));
m_logAction->setText(tr("Log %1").arg(fileName));
m_blameAction->setText(tr("Blame %1").arg(fileName));
m_undoFileAction->setText(tr("Undo changes for %1").arg(fileName));
m_addAction->setText(tr("Add %1").arg(fileName));
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_diffAction->setEnabled(false);
m_statusAction->setEnabled(false);
m_logAction->setEnabled(false);
m_blameAction->setEnabled(false);
m_undoFileAction->setEnabled(false);
m_addAction->setEnabled(false);
m_diffProjectAction->setEnabled(false);
m_diffProjectAction->setText(tr("Diff Project"));
m_statusProjectAction->setText(tr("Status Project"));
m_statusProjectAction->setEnabled(false);
m_logProjectAction->setText(tr("Log Project"));
m_logProjectAction->setEnabled(false);
return;
} else {
// We only know the file is in some repository, we do not know
// anything about any project so far.
m_diffAction->setEnabled(true);
m_statusAction->setEnabled(true);
m_logAction->setEnabled(true);
m_blameAction->setEnabled(true);
m_undoFileAction->setEnabled(true);
m_addAction->setEnabled(true);
}
if (m_projectExplorer && m_projectExplorer->currentNode()
&& m_projectExplorer->currentNode()->projectNode()) {
QString name = QFileInfo(m_projectExplorer->currentNode()->projectNode()->path()).baseName();
m_diffProjectAction->setEnabled(true);
m_diffProjectAction->setText(tr("Diff Project %1").arg(name));
m_statusProjectAction->setEnabled(true);
m_statusProjectAction->setText(tr("Status Project %1").arg(name));
m_logProjectAction->setEnabled(true);
m_logProjectAction->setText(tr("Log Project %1").arg(name));
} else {
m_diffProjectAction->setEnabled(false);
m_diffProjectAction->setText(tr("Diff Project"));
m_statusProjectAction->setEnabled(false);
m_statusProjectAction->setText(tr("Status Project"));
m_logProjectAction->setEnabled(false);
m_logProjectAction->setText(tr("Log Project"));
}
}
void GitPlugin::showCommit()
{
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 (m_changeSelectionDialog->exec() != QDialog::Accepted)
return;
const QString change = m_changeSelectionDialog->m_ui.changeNumberEdit->text();
if (change .isEmpty())
return;
m_gitClient->show(m_changeSelectionDialog->m_ui.repositoryEdit->text(), change);
}
Q_EXPORT_PLUGIN(GitPlugin)

163
src/plugins/git/gitplugin.h Normal file
View File

@@ -0,0 +1,163 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GITPLUGIN_H
#define GITPLUGIN_H
#include "gitoutputwindow.h"
#include "settingspage.h"
#include <coreplugin/editormanager/ieditorfactory.h>
#include <coreplugin/icorelistener.h>
#include <projectexplorer/ProjectExplorerInterfaces>
#include <extensionsystem/iplugin.h>
#include <QtCore/QObject>
#include <QtCore/QProcess>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QFile;
class QAction;
class QTemporaryFile;
QT_END_NAMESPACE
namespace Core {
class IEditorFactory;
class ICore;
}
namespace Git {
namespace Internal {
class GitPlugin;
class GitClient;
class ChangeSelectionDialog;
class GitSubmitEditor;
struct CommitData;
// 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
{
Q_OBJECT
public:
GitPlugin();
~GitPlugin();
static GitPlugin *instance();
bool vcsOpen(const QString &fileName);
bool initialize(const QStringList &arguments
, QString *error_message);
void extensionsInitialized();
QString getWorkingDirectory();
public slots:
void updateActions();
bool editorAboutToClose(Core::IEditor *editor);
private slots:
void diffCurrentFile();
void diffCurrentProject();
void submitEditorDiff(const QStringList &);
void submitCurrentLog();
void statusFile();
void statusProject();
void logFile();
void blameFile();
void logProject();
void undoFileChanges();
void undoProjectChanges();
void addFile();
void showCommit();
void startCommit();
void pull();
void push();
private:
friend class GitClient;
QFileInfo currentFile();
Core::IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd);
void cleanChangeTmpFile();
static GitPlugin *m_instance;
Core::ICore *m_core;
QAction *m_diffAction;
QAction *m_diffProjectAction;
QAction *m_statusAction;
QAction *m_statusProjectAction;
QAction *m_logAction;
QAction *m_blameAction;
QAction *m_logProjectAction;
QAction *m_undoFileAction;
QAction *m_undoProjectAction;
QAction *m_showAction;
QAction *m_addAction;
QAction *m_commitAction;
QAction *m_pullAction;
QAction *m_pushAction;
QAction *m_submitCurrentAction;
QAction *m_diffSelectedFilesAction;
QAction *m_undoAction;
QAction *m_redoAction;
ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer;
GitClient *m_gitClient;
GitOutputWindow *m_outputWindow;
ChangeSelectionDialog *m_changeSelectionDialog;
SettingsPage *m_settingsPage;
QList<Core::IEditorFactory*> m_editorFactories;
CoreListener *m_coreListener;
Core::IEditorFactory *m_submitEditorFactory;
QString m_submitRepository;
QTemporaryFile *m_changeTmpFile;
};
} // namespace Git
} // namespace Internal
#endif

View File

@@ -0,0 +1,92 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gitsubmiteditor.h"
#include "gitsubmiteditorwidget.h"
#include "gitconstants.h"
#include "commitdata.h"
#include <QtCore/QDebug>
namespace Git {
namespace Internal {
GitSubmitEditor::GitSubmitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, QWidget *parent) :
VCSBaseSubmitEditor(parameters, new GitSubmitEditorWidget(parent))
{
setDisplayName(tr("Git Commit"));
}
GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget()
{
return static_cast<GitSubmitEditorWidget *>(widget());
}
QStringList GitSubmitEditor::vcsFileListToFileList(const QStringList &rawList) const
{
QStringList rc;
foreach (const QString &rf, rawList)
rc.push_back(fileFromChangeLine(rf));
return rc;
}
void GitSubmitEditor::setCommitData(const CommitData &d)
{
submitEditorWidget()->setPanelData(d.panelData);
submitEditorWidget()->setPanelInfo(d.panelInfo);
// Commited: Checked, user cannot uncheck
addFiles(d.commitFiles, true, false);
// Not Updated: User can check
addFiles(d.notUpdatedFiles, false, true);
addFiles(d.untrackedFiles, false, true);
}
GitSubmitEditorPanelData GitSubmitEditor::panelData() const
{
return const_cast<GitSubmitEditor*>(this)->submitEditorWidget()->panelData();
}
QString GitSubmitEditor::fileFromChangeLine(const QString &line)
{
QString rc = line;
// "modified: mainwindow.cpp"
const int index = rc.indexOf(QLatin1Char(':'));
if (index != -1)
rc.remove(0, index + 1);
const QChar blank(' ');
while (rc.startsWith(blank))
rc.remove(0, 1);
return rc;
}
}
}

View File

@@ -0,0 +1,67 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GITSUBMITEDITOR_H
#define GITSUBMITEDITOR_H
#include <vcsbase/vcsbasesubmiteditor.h>
namespace Git {
namespace Internal {
class GitSubmitEditorWidget;
struct CommitData;
struct GitSubmitEditorPanelData;
/* */
class GitSubmitEditor : public VCSBase::VCSBaseSubmitEditor
{
Q_OBJECT
public:
explicit GitSubmitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, QWidget *parent);
void setCommitData(const CommitData &);
GitSubmitEditorPanelData panelData() const;
static QString fileFromChangeLine(const QString &line);
protected:
virtual QStringList vcsFileListToFileList(const QStringList &) const;
private:
inline GitSubmitEditorWidget *submitEditorWidget();
};
} // namespace Internal
} // namespace Git
#endif // GITSUBMITEDITOR_H

View File

@@ -0,0 +1,69 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "gitsubmiteditorwidget.h"
#include "commitdata.h"
namespace Git {
namespace Internal {
GitSubmitEditorWidget::GitSubmitEditorWidget(QWidget *parent) :
Core::Utils::SubmitEditorWidget(parent),
m_gitSubmitPanel(new QWidget)
{
m_gitSubmitPanelUi.setupUi(m_gitSubmitPanel);
insertTopWidget(m_gitSubmitPanel);
}
void GitSubmitEditorWidget::setPanelInfo(const GitSubmitEditorPanelInfo &info)
{
m_gitSubmitPanelUi.repositoryLabel->setText(info.repository);
m_gitSubmitPanelUi.descriptionLabel->setText(info.description);
m_gitSubmitPanelUi.branchLabel->setText(info.branch);
}
GitSubmitEditorPanelData GitSubmitEditorWidget::panelData() const
{
GitSubmitEditorPanelData rc;
rc.author = m_gitSubmitPanelUi.authorLineEdit->text();
rc.email = m_gitSubmitPanelUi.emailLineEdit->text();
return rc;
};
void GitSubmitEditorWidget::setPanelData(const GitSubmitEditorPanelData &data)
{
m_gitSubmitPanelUi.authorLineEdit->setText(data.author);
m_gitSubmitPanelUi.emailLineEdit->setText(data.email);
}
}
}

View File

@@ -0,0 +1,73 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef GITSUBMITEDITORWIDGET_H
#define GITSUBMITEDITORWIDGET_H
#include "ui_gitsubmitpanel.h"
#include <utils/submiteditorwidget.h>
namespace Git {
namespace Internal {
struct GitSubmitEditorPanelInfo;
struct GitSubmitEditorPanelData;
/* Submit editor widget with 2 additional panes:
* 1) Info with branch, description, etc
* 2) Data, with author and email to edit.
* The file contents is the submit message.
* The previously added files will be added 'checked' to the file list, the
* remaining un-added and untracked files will be added 'unchecked' for the
* user to click. */
class GitSubmitEditorWidget : public Core::Utils::SubmitEditorWidget
{
public:
explicit GitSubmitEditorWidget(QWidget *parent = 0);
GitSubmitEditorPanelData panelData() const;
void setPanelData(const GitSubmitEditorPanelData &data);
void setPanelInfo(const GitSubmitEditorPanelInfo &info);
private:
QWidget *m_gitSubmitPanel;
Ui::GitSubmitPanel m_gitSubmitPanelUi;
};
} // namespace Internal
} // namespace Perforce
#endif // GITSUBMITEDITORWIDGET_H

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Git::Internal::GitSubmitPanel</class>
<widget class="QWidget" name="Git::Internal::GitSubmitPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>201</width>
<height>210</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="infoGroup">
<property name="title">
<string>General Information</string>
</property>
<layout class="QFormLayout" name="infoFormLayout">
<item row="0" column="0">
<widget class="QLabel" name="repositoryLabelLabel">
<property name="text">
<string>Repository:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="repositoryLabel">
<property name="text">
<string>repository</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="descriptionLabelLabel">
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="descriptionLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>description</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="branchLabelLabel">
<property name="text">
<string>Branch:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="branchLabel">
<property name="text">
<string>branch</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="editGroup">
<property name="title">
<string>Commit Information</string>
</property>
<layout class="QFormLayout" name="editFormLayout">
<item row="0" column="0">
<widget class="QLabel" name="authorLabel">
<property name="text">
<string>Author:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="authorLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="emailLabel">
<property name="text">
<string>Email:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="emailLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,115 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "settingspage.h"
#include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
#include <QtCore/QSettings>
#include <QtGui/QLineEdit>
#include <QtGui/QFileDialog>
#include <QtCore/QDebug>
using namespace Git::Internal;
static const char *groupC = "Git";
static const char *sysEnvKeyC = "SysEnv";
static const char *pathKeyC = "Path";
static const char *logCountKeyC = "LogCount";
SettingsPage::SettingsPage()
{
Core::ICore *coreIFace = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
if (coreIFace)
m_settings = coreIFace->settings();
if (m_settings) {
m_settings->beginGroup(QLatin1String(groupC));
m_adopt = m_settings->value(QLatin1String(sysEnvKeyC), true).toBool();
m_path = m_settings->value(QLatin1String(pathKeyC), QString()).toString();
m_logCount = m_settings->value(QLatin1String(logCountKeyC), 10).toInt();
m_settings->endGroup();
}
}
QString SettingsPage::name() const
{
return tr("General");
}
QString SettingsPage::category() const
{
return QLatin1String("Git");
}
QString SettingsPage::trCategory() const
{
return tr("Git");
}
QWidget *SettingsPage::createPage(QWidget *parent)
{
QWidget *w = new QWidget(parent);
m_ui.setupUi(w);
m_ui.adoptCheckBox->setChecked(m_adopt);
m_ui.pathLineEdit->setText(m_path);
m_ui.logLineEdit->setText(QString::number(m_logCount));
connect(m_ui.adoptButton, SIGNAL(clicked()), this, SLOT(setSystemPath()));
return w;
}
void SettingsPage::finished(bool accepted)
{
if (!accepted)
return;
m_adopt = m_ui.adoptCheckBox->isChecked();
m_path = m_ui.pathLineEdit->text();
m_logCount = m_ui.logLineEdit->text().toInt();
if (!m_settings)
return;
m_settings->beginGroup(QLatin1String(groupC));
m_settings->setValue(QLatin1String(sysEnvKeyC), m_adopt);
m_settings->setValue(QLatin1String(pathKeyC), m_path);
m_settings->setValue(QLatin1String(logCountKeyC), m_logCount);
m_settings->endGroup();
}
void SettingsPage::setSystemPath()
{
m_path = qgetenv("PATH");
m_ui.pathLineEdit->setText(m_path);
}

View File

@@ -0,0 +1,82 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef SETTINGSPAGE_H
#define SETTINGSPAGE_H
#include <QtGui/QWidget>
#include <coreplugin/dialogs/ioptionspage.h>
#include "ui_settingspage.h"
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace Git {
namespace Internal {
class SettingsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
SettingsPage();
QString name() const;
QString category() const;
QString trCategory() const;
QWidget *createPage(QWidget *parent);
void finished(bool accepted);
bool adoptEnvironment() const { return m_adopt; }
int logCount() const { return m_logCount; }
QString path() const { return m_path; }
private slots:
void setSystemPath();
private:
Ui_SettingsPage m_ui;
QSettings *m_settings;
bool m_adopt;
QString m_path;
int m_logCount;
};
} //namespace Internal
} //namespace Git
#endif

View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Git::Internal::SettingsPage</class>
<widget class="QWidget" name="Git::Internal::SettingsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>345</width>
<height>177</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="adoptCheckBox">
<property name="text">
<string>Use System Environment</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Environment variables</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>PATH:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="pathLineEdit"/>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="adoptButton">
<property name="text">
<string>Adopt</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>52</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; font-weight:600;&quot;&gt;Note&lt;/span&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt; that Git needs Perl in the environment as well&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Commit display count:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="logLineEdit">
<property name="toolTip">
<string>Note that huge amount of commits might take some time.</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>141</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>pathLineEdit</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>adoptCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>groupBox</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>144</x>
<y>33</y>
</hint>
<hint type="destinationlabel">
<x>139</x>
<y>65</y>
</hint>
</hints>
</connection>
</connections>
</ui>