Commit 5e8d179a authored by Friedemann Kleint's avatar Friedemann Kleint

Mercurial: Compile windows, use common output window.

Polish: Canconical slots, const-correctness, some QLatin1Strings/tr,
parent 6575e44b
......@@ -36,7 +36,7 @@ using namespace Mercurial;
MercurialAnnotationHighlighter::MercurialAnnotationHighlighter(const ChangeNumbers &changeNumbers,
QTextDocument *document)
: VCSBase::BaseAnnotationHighlighter(changeNumbers, document),
changeset(Constants::CHANGESETID12)
changeset(QLatin1String(Constants::CHANGESETID12))
{
}
......
......@@ -31,6 +31,7 @@
#define ANNOTATIONHIGHLIGHTER_H
#include <vcsbase/baseannotationhighlighter.h>
#include <QtCore/QRegExp>
namespace Mercurial {
namespace Internal {
......
......@@ -32,13 +32,15 @@
#include "mercurialplugin.h"
#include "mercurialsettings.h"
#include <vcsbase/checkoutjobs.h>
#include <QtCore/QDebug>
using namespace Mercurial::Internal;
CloneWizard::CloneWizard(QObject *parent)
: VCSBase::BaseCheckoutWizard(parent),
m_icon(QIcon(":/mercurial/images/hg.png"))
m_icon(QIcon(QLatin1String(":/mercurial/images/hg.png")))
{
}
......@@ -80,8 +82,8 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<
QString path = page->path();
QString directory = page->directory();
args << "clone" << page->repository() << directory;
*checkoutPath = path + "/" + directory;
args << QLatin1String("clone") << page->repository() << directory;
*checkoutPath = path + QLatin1Char('/') + directory;
return QSharedPointer<VCSBase::AbstractCheckoutJob>(new VCSBase::ProcessCheckoutJob(settings->binary(),
args, path));
......
......@@ -31,7 +31,6 @@
#define CLONEWIZARD_H
#include <vcsbase/basecheckoutwizard.h>
#include <vcsbase/checkoutjobs.h>
#include <QtGui/QIcon>
......@@ -53,7 +52,7 @@ protected:
QString *checkoutPath);
private:
QIcon m_icon;
const QIcon m_icon;
};
} //namespace Internal
......
......@@ -34,17 +34,18 @@ using namespace Mercurial::Internal;
CloneWizardPage::CloneWizardPage(QWidget *parent)
: VCSBase::BaseCheckoutWizardPage(parent)
{
setRepositoryLabel("Clone URL:");
setRepositoryLabel(tr("Clone URL:"));
}
QString CloneWizardPage::directoryFromRepository(const QString &repository) const
{
//mercruial repositories are generally of the form protocol://repositoryUrl/repository/
//mercurial repositories are generally of the form protocol://repositoryUrl/repository/
//we are just looking for repository.
const QChar slash = QLatin1Char('/');
QString repo = repository.trimmed();
if (repo.endsWith('/'))
repo = repo.remove(-1, 1);
if (repo.endsWith(slash))
repo.truncate(repo.size() - 1);
//Take the basename or the repository url
return repo.mid(repo.lastIndexOf('/') + 1);
return repo.mid(repo.lastIndexOf(slash) + 1);
}
......@@ -33,7 +33,7 @@
namespace Mercurial {
namespace Constants {
enum { debug = 1 };
enum { debug = 0 };
const char * const MERCURIAL = "mercurial";
const char * const MECURIALREPO = ".hg";
const char * const MERCURIALDEFAULT = "hg";
......@@ -52,9 +52,6 @@ const char * const CHANGESETID40 = " ([a-f0-9]{40,40}) ";
const char * const CHANGEIDEXACT12 = "[a-f0-9]{12,12}"; //match 12 hex chars a
const char * const CHANGEIDEXACT40 = "[a-f0-9]{40,40}";
const char * const DIFFIDENTIFIER = "^[-+]{3,3} [ab]{1,1}.*"; // match e.g. +++ b/filename
//Errors
const char * const ERRORSTARTING = "Unable to start Mercurial Process";
const char * const TIMEDOUT = "Timed out waiting for Mercurail Process to Finish";
//BaseEditorParameters
const char * const COMMANDLOG = "Mercurial Command Log Editor";
......
......@@ -4,7 +4,6 @@ include(../../qtcreatorplugin.pri)
include(mercurial_dependencies.pri)
SOURCES += mercurialplugin.cpp \
optionspage.cpp \
mercurialoutputwindow.cpp \
mercurialcontrol.cpp \
mercurialclient.cpp \
mercurialjobrunner.cpp \
......@@ -20,7 +19,6 @@ SOURCES += mercurialplugin.cpp \
HEADERS += mercurialplugin.h \
constants.h \
optionspage.h \
mercurialoutputwindow.h \
mercurialcontrol.h \
mercurialclient.h \
mercurialjobrunner.h \
......
......@@ -45,6 +45,8 @@
#include <QtCore/QProcess>
#include <QtCore/QTextCodec>
#include <QtCore/QtDebug>
#include <QtCore/QFileInfo>
#include <QtCore/QByteArray>
using namespace Mercurial::Internal;
using namespace Mercurial;
......@@ -249,12 +251,11 @@ void MercurialClient::status(const QFileInfo &fileOrDir)
void MercurialClient::statusWithSignal(const QFileInfo &repositoryRoot)
{
QStringList args;
args << "status";
const QStringList args(QLatin1String("status"));
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, true));
connect(job.data(), SIGNAL(rawData(const QByteArray &)),
this, SLOT(statusParser(const QByteArray &)));
connect(job.data(), SIGNAL(rawData(QByteArray)),
this, SLOT(statusParser(QByteArray)));
jobManager->enqueueJob(job);
}
......
......@@ -31,10 +31,12 @@
#define MERCURIALCLIENT_H
#include <QtCore/QObject>
#include <QtCore/QFileInfo>
#include <QtCore/QByteArray>
#include <QtCore/QPair>
QT_BEGIN_NAMESPACE
class QFileInfo;
QT_END_NAMESPACE
namespace Core {
class ICore;
}
......
......@@ -133,7 +133,7 @@ void MercurialCommitWidget::setFields(const QString &repositoryRoot, const QStri
QString MercurialCommitWidget::committer()
{
QString user = mercurialCommitPanelUi.authorLineEdit->text() + QLatin1String(" <") +
mercurialCommitPanelUi.emailLineEdit->text() + QLatin1String(">");
mercurialCommitPanelUi.emailLineEdit->text() + QLatin1Char('>');
return user;
}
......
......@@ -35,11 +35,11 @@
#include <coreplugin/editormanager/editormanager.h>
#include <vcsbase/diffhighlighter.h>
#include <QtCore/QSet>
#include <QtCore/QString>
#include <QtGui/QTextCursor>
#include <QtGui/QTextBlock>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
using namespace Mercurial::Internal;
......@@ -97,15 +97,15 @@ VCSBase::BaseAnnotationHighlighter *MercurialEditor::createAnnotationHighlighter
QString MercurialEditor::fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const
{
QString filechangeId("+++ b/");
const QString filechangeId(QLatin1String("+++ b/"));
QTextBlock::iterator iterator;
for (iterator = diffFileSpec.begin(); !(iterator.atEnd()); iterator++) {
QTextFragment fragment = iterator.fragment();
if(fragment.isValid()) {
if (fragment.text().startsWith(filechangeId)) {
QFileInfo sourceFile(source());
QDir repository(MercurialClient::findTopLevelForFile(sourceFile));
QString filename = fragment.text().remove(0, filechangeId.size());
const QFileInfo sourceFile(source());
const QDir repository(MercurialClient::findTopLevelForFile(sourceFile));
const QString filename = fragment.text().remove(0, filechangeId.size());
return repository.absoluteFilePath(filename);
}
}
......
......@@ -29,10 +29,10 @@
#include "mercurialjobrunner.h"
#include "mercurialplugin.h"
#include "mercurialoutputwindow.h"
#include "constants.h"
#include "mercurialsettings.h"
#include <vcsbase/vcsbaseoutputwindow.h>
#include <vcsbase/vcsbaseeditor.h>
#include <QtCore/QProcess>
......@@ -44,7 +44,7 @@
using namespace Mercurial::Internal;
using namespace Mercurial;
HgTask::HgTask(const QString &repositoryRoot, QStringList &arguments, bool emitRaw)
HgTask::HgTask(const QString &repositoryRoot, const QStringList &arguments, bool emitRaw)
: m_repositoryRoot(repositoryRoot),
arguments(arguments),
emitRaw(emitRaw),
......@@ -52,23 +52,22 @@ HgTask::HgTask(const QString &repositoryRoot, QStringList &arguments, bool emitR
{
}
HgTask::HgTask(const QString &repositoryRoot, QStringList &arguments, VCSBase::VCSBaseEditor *editor)
HgTask::HgTask(const QString &repositoryRoot, const QStringList &arguments, VCSBase::VCSBaseEditor *editor)
: m_repositoryRoot(repositoryRoot),
arguments(arguments),
emitRaw(false),
editor(editor)
{
}
MercurialJobRunner::MercurialJobRunner()
: keepRunning(true)
MercurialJobRunner::MercurialJobRunner() :
plugin(MercurialPlugin::instance()),
keepRunning(true)
{
plugin = MercurialPlugin::instance();
connect(this, SIGNAL(error(const QByteArray &)), plugin->outputPane(), SLOT(append(const QByteArray &)));
connect(this, SIGNAL(info(const QString &)), plugin->outputPane(), SLOT(append(const QString &)));
VCSBase::VCSBaseOutputWindow *ow = VCSBase::VCSBaseOutputWindow::instance();
connect(this, SIGNAL(error(QString)), ow, SLOT(appendError(QString)), Qt::QueuedConnection);
connect(this, SIGNAL(commandStarted(QString)), ow, SLOT(appendCommand(QString)), Qt::QueuedConnection);
}
MercurialJobRunner::~MercurialJobRunner()
......@@ -106,7 +105,7 @@ void MercurialJobRunner::getSettings()
standardArguments = settings->standardArguments();
}
void MercurialJobRunner::enqueueJob(QSharedPointer<HgTask> &job)
void MercurialJobRunner::enqueueJob(const QSharedPointer<HgTask> &job)
{
mutex.lock();
jobs.enqueue(job);
......@@ -135,28 +134,32 @@ void MercurialJobRunner::run()
}
}
void MercurialJobRunner::task(QSharedPointer<HgTask> &job)
void MercurialJobRunner::task(const QSharedPointer<HgTask> &job)
{
HgTask *taskData = job.data();
if (taskData->shouldEmit())
VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
if (taskData->shouldEmit()) {
//Call the job's signal so the Initator of the job can process the data
//Because the QSharedPointer that holds the HgTask will go out of scope and hence be deleted
//we have to block and wait until the signal is delivered
connect(this, SIGNAL(output(const QByteArray&)), taskData, SIGNAL(rawData(const QByteArray&)),
connect(this, SIGNAL(output(QByteArray)), taskData, SIGNAL(rawData(QByteArray)),
Qt::BlockingQueuedConnection);
else if (taskData->displayEditor())
} else if (taskData->displayEditor()) {
//An editor has been created to display the data so send it there
connect(this, SIGNAL(output(const QByteArray&)), taskData->displayEditor(), SLOT(setPlainTextData(const QByteArray&)));
else
connect(this, SIGNAL(output(QByteArray)),
taskData->displayEditor(), SLOT(setPlainTextData(QByteArray)),
Qt::QueuedConnection);
} else {
//Just output the data to the Mercurial output window
connect(this, SIGNAL(output(const QByteArray &)), plugin->outputPane(), SLOT(append(const QByteArray &)));
QString time = QTime::currentTime().toString(QLatin1String("HH:mm"));
QString starting = tr("%1 Calling: %2 %3\n").arg(time, "hg", taskData->args().join(" "));
connect(this, SIGNAL(output(QByteArray)), outputWindow, SLOT(appendData(QByteArray)),
Qt::QueuedConnection);
}
const QString starting = tr("Executing: %1 %2\n").arg(binary, taskData->args().join(QString(QLatin1Char(' '))));
emit commandStarted(starting);
//infom the user of what we are going to try and perform
emit info(starting);
if (Constants::debug)
qDebug() << Q_FUNC_INFO << "Repository root is " << taskData->repositoryRoot();
......@@ -170,8 +173,7 @@ void MercurialJobRunner::task(QSharedPointer<HgTask> &job)
hgProcess.start(binary, args);
if (!hgProcess.waitForStarted()) {
QByteArray errorArray(Constants::ERRORSTARTING);
emit error(errorArray);
emit error(tr("Unable to start mercurial process '%1': %2").arg(binary, hgProcess.errorString()));
return;
}
......@@ -179,28 +181,26 @@ void MercurialJobRunner::task(QSharedPointer<HgTask> &job)
if (!hgProcess.waitForFinished(timeout)) {
hgProcess.terminate();
QByteArray errorArray(Constants::TIMEDOUT);
emit error(errorArray);
emit error(tr("Timed out waiting for mercurial process to finish."));
return;
}
if ((hgProcess.exitStatus() == QProcess::NormalExit) && (hgProcess.exitCode() == 0)) {
QByteArray stdout = hgProcess.readAllStandardOutput();
QByteArray stdOutput= hgProcess.readAllStandardOutput();
/*
* sometimes success means output is actually on error channel (stderr)
* e.g. "hg revert" outputs "no changes needed to 'file'" on stderr if file has not changed
* from revision specified
*/
if (stdout == "")
stdout = hgProcess.readAllStandardError();
emit output(stdout);
if (stdOutput.isEmpty())
stdOutput = hgProcess.readAllStandardError();
emit output(stdOutput);
} else {
QByteArray stderr = hgProcess.readAllStandardError();
emit error(stderr);
emit error(QString::fromLocal8Bit(hgProcess.readAllStandardError()));
}
hgProcess.close();
//the signal connection is to last only for the duration of a job/task. next time a new
//output signal connection must be made
disconnect(this, SIGNAL(output(const QByteArray &)), 0, 0);
disconnect(this, SIGNAL(output(QByteArray)), 0, 0);
}
......@@ -51,8 +51,8 @@ class HgTask : public QObject
{
Q_OBJECT
public:
HgTask(const QString &workingDir, QStringList &arguments, bool emitRaw=false);
HgTask(const QString &workingDir, QStringList &arguments,
HgTask(const QString &workingDir, const QStringList &arguments, bool emitRaw=false);
HgTask(const QString &workingDir, const QStringList &arguments,
VCSBase::VCSBaseEditor *editor);
bool shouldEmit() { return emitRaw; }
......@@ -64,9 +64,9 @@ signals:
void rawData(const QByteArray &data);
private:
QString m_repositoryRoot;
QStringList arguments;
bool emitRaw;
const QString m_repositoryRoot;
const QStringList arguments;
const bool emitRaw;
VCSBase::VCSBaseEditor *editor;
};
......@@ -77,19 +77,19 @@ class MercurialJobRunner : public QThread
public:
MercurialJobRunner();
~MercurialJobRunner();
void enqueueJob(QSharedPointer<HgTask> &job);
void enqueueJob(const QSharedPointer<HgTask> &job);
void restart();
protected:
void run();
signals:
void error(const QByteArray &error);
void info(const QString &notice);
void commandStarted(const QString &notice);
void error(const QString &error);
void output(const QByteArray &output);
private:
void task(QSharedPointer<HgTask> &job);
void task(const QSharedPointer<HgTask> &job);
void stop();
void getSettings();
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Brian McGillion
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "mercurialoutputwindow.h"
#include <QtGui/QListWidget>
#include <QtCore/QDebug>
#include <QtCore/QTextCodec>
using namespace Mercurial::Internal;
MercurialOutputWindow::MercurialOutputWindow()
{
outputListWidgets = new QListWidget;
outputListWidgets->setWindowTitle(tr("Mercurial Output"));
outputListWidgets->setFrameStyle(QFrame::NoFrame);
outputListWidgets->setSelectionMode(QAbstractItemView::ExtendedSelection);
}
MercurialOutputWindow::~MercurialOutputWindow()
{
delete outputListWidgets;
outputListWidgets = 0;
}
QWidget *MercurialOutputWindow::outputWidget(QWidget *parent)
{
outputListWidgets->setParent(parent);
return outputListWidgets;
}
QList<QWidget*> MercurialOutputWindow::toolBarWidgets() const
{
return QList<QWidget *>();
}
QString MercurialOutputWindow::name() const
{
return tr("Mercurial");
}
int MercurialOutputWindow::priorityInStatusBar() const
{
return -1;
}
void MercurialOutputWindow::clearContents()
{
outputListWidgets->clear();
}
void MercurialOutputWindow::visibilityChanged(bool visible)
{
if (visible)
outputListWidgets->setFocus();
}
void MercurialOutputWindow::setFocus()
{
}
bool MercurialOutputWindow::hasFocus()
{
return outputListWidgets->hasFocus();
}
bool MercurialOutputWindow::canFocus()
{
return false;
}
bool MercurialOutputWindow::canNavigate()
{
return false;
}
bool MercurialOutputWindow::canNext()
{
return false;
}
bool MercurialOutputWindow::canPrevious()
{
return false;
}
void MercurialOutputWindow::goToNext()
{
}
void MercurialOutputWindow::goToPrev()
{
}
void MercurialOutputWindow::append(const QString &text)
{
outputListWidgets->addItems(text.split(QLatin1Char('\n')));
outputListWidgets->scrollToBottom();
popup(true);
}
void MercurialOutputWindow::append(const QByteArray &array)
{
append(QTextCodec::codecForLocale()->toUnicode(array));
}
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Brian McGillion
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef MERCURIALOUTPUTWINDOW_H
#define MERCURIALOUTPUTWINDOW_H
#include <coreplugin/ioutputpane.h>
QT_BEGIN_NAMESPACE
class QListWidget;
QT_END_NAMESPACE
#include <QtCore/QByteArray>
namespace Mercurial {
namespace Internal {
class MercurialOutputWindow: public Core::IOutputPane
{
Q_OBJECT
public:
MercurialOutputWindow();
~MercurialOutputWindow();
QWidget *outputWidget(QWidget *parent);
QList<QWidget*> toolBarWidgets() const;
QString name() const;
int priorityInStatusBar() const;
void clearContents();
void visibilityChanged(bool visible);
void setFocus();
bool hasFocus();
bool canFocus();
bool canNavigate();
bool canNext();
bool canPrevious();
void goToNext();
void goToPrev();
public slots:
void append(const QString &text);
void append(const QByteArray &array);
private:
QListWidget *outputListWidgets;
};
} //namespace Internal
} //namespace Mercurial
#endif // MERCURIALOUTPUTWINDOW_H
......@@ -29,7 +29,6 @@
#include "mercurialplugin.h"
#include "optionspage.h"
#include "mercurialoutputwindow.h"
#include "constants.h"
#include "mercurialclient.h"
#include "mercurialcontrol.h"
......@@ -57,6 +56,7 @@
#include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/basevcssubmiteditorfactory.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseoutputwindow.h>
#include <QtCore/QtPlugin>
#include <QtGui/QAction>
......@@ -123,7 +123,6 @@ MercurialPlugin *MercurialPlugin::m_instance = 0;
MercurialPlugin::MercurialPlugin()
: mercurialSettings(new MercurialSettings),
outputWindow(0),
optionsPage(0),
client(0),
mercurialVC(0),
......@@ -163,9 +162,6 @@ bool MercurialPlugin::initialize(const QStringList &arguments, QString *error_me
optionsPage = new OptionsPage();
addAutoReleasedObject(optionsPage);
outputWindow = new MercurialOutputWindow();
addAutoReleasedObject(outputWindow);
client = new MercurialClient();
connect(optionsPage, SIGNAL(settingsChanged()), client, SLOT(settingsChanged()));
......@@ -198,11 +194,6 @@ void MercurialPlugin::extensionsInitialized()
this, SLOT(currentProjectChanged(ProjectExplorer::Project *)));
}
MercurialOutputWindow *MercurialPlugin::outputPane()
{
return outputWindow;
}
MercurialSettings *MercurialPlugin::settings()
{
return mercurialSettings;
......@@ -300,8 +291,7 @@ void MercurialPlugin::revertCurrentFile()
RevertDialog reverter;
if (reverter.exec() != QDialog::Accepted)
return;
const QString revision = reverter.m_ui->revisionLineEdit->text();
client->revert(currentFile(), revision);
client->revert(currentFile(), reverter.revision());
}