Commit 0c50c5a1 authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh
Browse files

VCS: Consolidate codec handling



Change-Id: I2c9a5031b63f0bc3e884739be680d051d7cf1ab4
Reviewed-by: default avatarFriedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent a1e9b81c
......@@ -132,9 +132,9 @@ public:
void show(const QString &id);
private slots:
void slotShowDescriptionReceived(const QByteArray &data);
void slotFileListReceived(const QByteArray &data);
void slotFileContentsReceived(const QByteArray &data);
void slotShowDescriptionReceived(const QString &data);
void slotFileListReceived(const QString &fileList);
void slotFileContentsReceived(const QString &contents);
private:
void collectShowDescription(const QString &id);
......@@ -259,7 +259,8 @@ void GitDiffHandler::collectShowDescription(const QString &id)
return;
m_editor->clear(m_waitMessage);
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotShowDescriptionReceived(QByteArray)));
command->setCodec(m_editor->editorWidget()->codec());
connect(command, SIGNAL(outputData(QString)), this, SLOT(slotShowDescriptionReceived(QString)));
QStringList arguments;
arguments << QLatin1String("show") << QLatin1String("-s") << QLatin1String("--format=fuller")
<< QLatin1String(noColorOption) << QLatin1String(decorateOption) << id;
......@@ -267,12 +268,10 @@ void GitDiffHandler::collectShowDescription(const QString &id)
command->execute();
}
void GitDiffHandler::slotShowDescriptionReceived(const QByteArray &data)
void GitDiffHandler::slotShowDescriptionReceived(const QString &description)
{
if (m_editor.isNull())
return;
const QString description = m_editor->editorWidget()->codec()->toUnicode(data).remove(QLatin1Char('\r'));
DiffEditor::DiffShowEditor *editor = qobject_cast<DiffEditor::DiffShowEditor *>(m_editor);
if (editor)
editor->setDescription(description);
......@@ -288,19 +287,19 @@ void GitDiffHandler::collectFilesList(const QStringList &additionalArguments)
return;
m_editor->clear(m_waitMessage);
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotFileListReceived(QByteArray)));
command->setCodec(m_editor->editorWidget()->codec());
connect(command, SIGNAL(outputData(QString)), this, SLOT(slotFileListReceived(QString)));
QStringList arguments;
arguments << QLatin1String("diff") << QLatin1String("--name-only") << additionalArguments;
command->addJob(arguments, m_timeout);
command->execute();
}
void GitDiffHandler::slotFileListReceived(const QByteArray &data)
void GitDiffHandler::slotFileListReceived(const QString &fileList)
{
if (m_editor.isNull())
return;
const QString fileList = m_editor->editorWidget()->codec()->toUnicode(data).remove(QLatin1Char('\r'));
QStringList fileNames = fileList.split(QLatin1Char('\n'), QString::SkipEmptyParts);
fileNames.removeDuplicates();
......@@ -355,7 +354,9 @@ void GitDiffHandler::collectFilesContents()
// prepare job here
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotFileContentsReceived(QByteArray)));
if (m_editor)
command->setCodec(m_editor->editorWidget()->codec());
connect(command, SIGNAL(outputData(QString)), this, SLOT(slotFileContentsReceived(QString)));
QString revisionArgument = (revision.type == Other)
? revision.id : QString();
......@@ -375,7 +376,7 @@ void GitDiffHandler::collectFilesContents()
feedEditor();
}
void GitDiffHandler::slotFileContentsReceived(const QByteArray &data)
void GitDiffHandler::slotFileContentsReceived(const QString &contents)
{
if (m_editor.isNull())
return;
......@@ -392,7 +393,6 @@ void GitDiffHandler::slotFileContentsReceived(const QByteArray &data)
QMap<Revision, bool>::iterator itRevEnd
= revisions.end();
if (itRev != itRevEnd) {
const QString contents = m_editor->editorWidget()->codec()->toUnicode(data).remove(QLatin1Char('\r'));
m_collectedRevisions[fileName][itRev.key()] = contents;
itRev = revisions.erase(itRev);
......@@ -690,7 +690,7 @@ public:
{
if (parentCommand) {
parentCommand->setExpectChanges(true);
connect(parentCommand, SIGNAL(outputData(QByteArray)), this, SLOT(readStdOut(QByteArray)));
connect(parentCommand, SIGNAL(outputData(QString)), this, SLOT(readStdOut(QString)));
connect(parentCommand, SIGNAL(errorText(QString)), this, SLOT(readStdErr(QString)));
}
}
......@@ -706,7 +706,8 @@ public:
}
}
void readStdOutString(const QString &data)
public slots:
void readStdOut(const QString &data)
{
static QRegExp patchFailedRE(QLatin1String("Patch failed at ([^\\n]*)"));
static QRegExp conflictedFilesRE(QLatin1String("Merge conflict in ([^\\n]*)"));
......@@ -717,11 +718,6 @@ public:
m_files.append(conflictedFilesRE.cap(1));
}
}
public slots:
void readStdOut(const QByteArray &data)
{
readStdOutString(QString::fromUtf8(data));
}
void readStdErr(const QString &data)
{
......@@ -1231,16 +1227,14 @@ void GitClient::slotBlameRevisionRequested(const QString &source, QString change
blame(fi.absolutePath(), QStringList(), fi.fileName(), change, lineNumber);
}
void GitClient::appendOutputData(const QByteArray &data) const
void GitClient::appendOutputData(const QString &data) const
{
const QTextCodec *codec = getSourceCodec(currentDocumentPath());
outputWindow()->appendData(codec->toUnicode(data).toLocal8Bit());
outputWindow()->append(data);
}
void GitClient::appendOutputDataSilently(const QByteArray &data) const
void GitClient::appendOutputDataSilently(const QString &data) const
{
const QTextCodec *codec = getSourceCodec(currentDocumentPath());
outputWindow()->appendDataSilently(codec->toUnicode(data).toLocal8Bit());
outputWindow()->appendSilently(data);
}
QTextCodec *GitClient::getSourceCodec(const QString &file) const
......@@ -1774,17 +1768,19 @@ QString GitClient::synchronousTopRevision(const QString &workingDirectory, QStri
}
void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const QString &revision,
QByteArray &precedes, QByteArray &follows)
QString &precedes, QString &follows)
{
QByteArray pr;
QStringList arguments;
arguments << QLatin1String("describe") << QLatin1String("--contains") << revision;
fullySynchronousGit(workingDirectory, arguments, &precedes, 0,
fullySynchronousGit(workingDirectory, arguments, &pr, 0,
VcsBasePlugin::SuppressCommandLogging);
int tilde = precedes.indexOf('~');
int tilde = pr.indexOf('~');
if (tilde != -1)
precedes.truncate(tilde);
pr.truncate(tilde);
else
precedes = precedes.trimmed();
pr = pr.trimmed();
precedes = QString::fromLocal8Bit(pr);
QStringList parents;
QString errorMessage;
......@@ -1799,8 +1795,8 @@ void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const
pf.truncate(pf.lastIndexOf('\n'));
if (!pf.isEmpty()) {
if (!follows.isEmpty())
follows += ", ";
follows += pf;
follows += QLatin1String(", ");
follows += QString::fromLocal8Bit(pf);
}
}
}
......@@ -2214,17 +2210,18 @@ VcsBase::Command *GitClient::createCommand(const QString &workingDirectory,
int editorLineNumber)
{
VcsBase::Command *command = new VcsBase::Command(gitBinaryPath(), workingDirectory, processEnvironment());
command->setCodec(getSourceCodec(currentDocumentPath()));
command->setCookie(QVariant(editorLineNumber));
if (editor)
connect(command, SIGNAL(finished(bool,int,QVariant)), editor, SLOT(commandFinishedGotoLine(bool,int,QVariant)));
if (useOutputToWindow) {
if (editor) // assume that the commands output is the important thing
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendOutputDataSilently(QByteArray)));
connect(command, SIGNAL(outputData(QString)), this, SLOT(appendOutputDataSilently(QString)));
else
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendOutputData(QByteArray)));
connect(command, SIGNAL(outputData(QString)), this, SLOT(appendOutputData(QString)));
} else {
if (editor)
connect(command, SIGNAL(outputData(QByteArray)), editor, SLOT(setPlainTextDataFiltered(QByteArray)));
connect(command, SIGNAL(outputData(QString)), editor, SLOT(setPlainTextDataFiltered(QString)));
}
connect(command, SIGNAL(errorText(QString)), outputWindow(), SLOT(appendError(QString)));
......@@ -3018,7 +3015,7 @@ bool GitClient::executeAndHandleConflicts(const QString &workingDirectory,
// Notify about changed files or abort the rebase.
const bool ok = resp.result == Utils::SynchronousProcessResponse::Finished;
if (!ok) {
conflictHandler.readStdOutString(resp.stdOut);
conflictHandler.readStdOut(resp.stdOut);
conflictHandler.readStdErr(resp.stdErr);
}
return ok;
......
......@@ -234,7 +234,7 @@ public:
QString synchronousTopic(const QString &workingDirectory);
QString synchronousTopRevision(const QString &workingDirectory, QString *errorMessage = 0);
void synchronousTagsForCommit(const QString &workingDirectory, const QString &revision,
QByteArray &precedes, QByteArray &follows);
QString &precedes, QString &follows);
bool isRemoteCommit(const QString &workingDirectory, const QString &commit);
bool cloneRepository(const QString &directory, const QByteArray &url);
......@@ -327,8 +327,8 @@ public slots:
private slots:
void slotBlameRevisionRequested(const QString &source, QString change, int lineNumber);
void appendOutputData(const QByteArray &data) const;
void appendOutputDataSilently(const QByteArray &data) const;
void appendOutputData(const QString &data) const;
void appendOutputDataSilently(const QString &data) const;
void finishSubmoduleUpdate();
void fetchFinished(const QVariant &cookie);
......
......@@ -118,25 +118,26 @@ VcsBase::BaseAnnotationHighlighter *GitEditor::createAnnotationHighlighter(const
8ca887aa (author YYYY-MM-DD HH:MM:SS <offset> <line>)<content>
\endcode */
static QByteArray removeAnnotationDate(const QByteArray &b)
static QString removeAnnotationDate(const QString &b)
{
if (b.isEmpty())
return QByteArray();
return b;
const int parenPos = b.indexOf(')');
const QChar space(QLatin1Char(' '));
const int parenPos = b.indexOf(QLatin1Char(')'));
if (parenPos == -1)
return QByteArray(b);
return b;
int datePos = parenPos;
int i = parenPos;
while (i >= 0 && b.at(i) != ' ')
while (i >= 0 && b.at(i) != space)
--i;
while (i >= 0 && b.at(i) == ' ')
while (i >= 0 && b.at(i) == space)
--i;
int spaceCount = 0;
// i is now on timezone. Go back 3 spaces: That is where the date starts.
while (i >= 0) {
if (b.at(i) == ' ')
if (b.at(i) == space)
++spaceCount;
if (spaceCount == 3) {
datePos = i;
......@@ -145,33 +146,33 @@ static QByteArray removeAnnotationDate(const QByteArray &b)
--i;
}
if (datePos == 0)
return QByteArray(b);
return b;
// Copy over the parts that have not changed into a new byte array
QByteArray result;
QString result;
QTC_ASSERT(b.size() >= parenPos, return result);
int prevPos = 0;
int pos = b.indexOf('\n', 0) + 1;
int pos = b.indexOf(QLatin1Char('\n'), 0) + 1;
forever {
QTC_CHECK(prevPos < pos);
int afterParen = prevPos + parenPos;
result.append(b.constData() + prevPos, datePos);
result.append(b.constData() + afterParen, pos - afterParen);
result.append(b.mid(prevPos, datePos));
result.append(b.mid(afterParen, pos - afterParen));
prevPos = pos;
QTC_CHECK(prevPos != 0);
if (pos == b.size())
break;
pos = b.indexOf('\n', pos) + 1;
pos = b.indexOf(QLatin1Char('\n'), pos) + 1;
if (pos == 0) // indexOf returned -1
pos = b.size();
}
return result;
}
void GitEditor::setPlainTextDataFiltered(const QByteArray &a)
void GitEditor::setPlainTextDataFiltered(const QString &a)
{
QByteArray array = a;
QString array = a;
GitPlugin *plugin = GitPlugin::instance();
// If desired, filter out the date from annotation
switch (contentType())
......@@ -184,17 +185,17 @@ void GitEditor::setPlainTextDataFiltered(const QByteArray &a)
}
case VcsBase::DiffOutput: {
if (array.isEmpty())
array = QByteArray("No difference to HEAD");
array = QLatin1String("No difference to HEAD");
const QFileInfo fi(source());
const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
QByteArray precedes, follows;
if (array.startsWith("commit ")) { // show
int lastHeaderLine = array.indexOf("\n\n") + 1;
plugin->gitClient()->synchronousTagsForCommit(workingDirectory, QLatin1String(array.mid(7, 8)), precedes, follows);
QString precedes, follows;
if (array.startsWith(QLatin1String("commit "))) { // show
int lastHeaderLine = array.indexOf(QLatin1String("\n\n")) + 1;
plugin->gitClient()->synchronousTagsForCommit(workingDirectory, array.mid(7, 8), precedes, follows);
if (!precedes.isEmpty())
array.insert(lastHeaderLine, "Precedes: " + precedes + '\n');
array.insert(lastHeaderLine, QLatin1String("Precedes: ") + precedes + QLatin1Char('\n'));
if (!follows.isEmpty())
array.insert(lastHeaderLine, "Follows: " + follows + '\n');
array.insert(lastHeaderLine, QLatin1String("Follows: ") + follows + QLatin1Char('\n'));
}
break;
}
......@@ -202,7 +203,7 @@ void GitEditor::setPlainTextDataFiltered(const QByteArray &a)
break;
}
setPlainTextData(array);
setPlainText(array);
}
void GitEditor::commandFinishedGotoLine(bool ok, int exitCode, const QVariant &v)
......
......@@ -50,7 +50,7 @@ public:
QWidget *parent);
public slots:
void setPlainTextDataFiltered(const QByteArray &a);
void setPlainTextDataFiltered(const QString &a);
// Matches the signature of the finished signal of GitCommand
void commandFinishedGotoLine(bool ok, int exitCode, const QVariant &v);
......
......@@ -43,6 +43,7 @@
#include <QCoreApplication>
#include <QVariant>
#include <QStringList>
#include <QTextCodec>
Q_DECLARE_METATYPE(QVariant)
......@@ -82,6 +83,7 @@ public:
bool m_unixTerminalDisabled;
int m_defaultTimeout;
bool m_expectChanges;
QTextCodec *m_codec;
QList<Job> m_jobs;
Command::TerminationReportMode m_reportTerminationMode;
......@@ -99,6 +101,7 @@ CommandPrivate::CommandPrivate(const QString &binary,
m_unixTerminalDisabled(false),
m_defaultTimeout(10),
m_expectChanges(false),
m_codec(0),
m_reportTerminationMode(Command::NoReport),
m_lastExecSuccess(false),
m_lastExecExitCode(-1)
......@@ -284,11 +287,15 @@ void Command::run()
}
}
QString stdOutS = d->m_codec ? d->m_codec->toUnicode(stdOut)
: QString::fromLocal8Bit(stdOut.constData(), stdOut.size());
stdOutS.remove(QLatin1Char('\r'));
d->m_lastExecSuccess = ok;
d->m_lastExecExitCode = exitCode;
if (ok)
emit outputData(stdOut);
emit outputData(stdOutS);
if (!error.isEmpty())
emit errorText(error);
......@@ -314,4 +321,14 @@ void Command::setCookie(const QVariant &cookie)
d->m_cookie = cookie;
}
QTextCodec *Command::codec() const
{
return d->m_codec;
}
void Command::setCodec(QTextCodec *codec)
{
d->m_codec = codec;
}
} // namespace VcsBase
......@@ -89,11 +89,14 @@ public:
const QVariant &cookie() const;
void setCookie(const QVariant &cookie);
QTextCodec *codec() const;
void setCodec(QTextCodec *codec);
private:
void run();
signals:
void outputData(const QByteArray &);
void outputData(const QString &);
void errorText(const QString &);
void finished(bool ok, int exitCode, const QVariant &cookie);
void success(const QVariant &cookie);
......
......@@ -89,7 +89,7 @@ class VcsBaseClientPrivate
public:
VcsBaseClientPrivate(VcsBaseClient *client, VcsBaseClientSettings *settings);
void statusParser(QByteArray data);
void statusParser(const QString &text);
void annotateRevision(QString source, QString change, int lineNumber);
void saveSettings();
......@@ -110,11 +110,11 @@ VcsBaseClientPrivate::VcsBaseClientPrivate(VcsBaseClient *client, VcsBaseClientS
{
}
void VcsBaseClientPrivate::statusParser(QByteArray data)
void VcsBaseClientPrivate::statusParser(const QString &text)
{
QList<VcsBaseClient::StatusItem> lineInfoList;
QStringList rawStatusList = QTextCodec::codecForLocale()->toUnicode(data).split(QLatin1Char('\n'));
QStringList rawStatusList = text.split(QLatin1Char('\n'));
foreach (const QString &string, rawStatusList) {
const VcsBaseClient::StatusItem lineInfo = m_client->parseStatusLine(string);
......@@ -436,7 +436,7 @@ void VcsBaseClient::emitParsedStatus(const QString &repository, const QStringLis
QStringList args(vcsCommandString(StatusCommand));
args << extraOptions;
Command *cmd = createCommand(repository);
connect(cmd, SIGNAL(outputData(QByteArray)), this, SLOT(statusParser(QByteArray)));
connect(cmd, SIGNAL(outputData(QString)), this, SLOT(statusParser(QString)));
enqueueJob(cmd, args);
}
......@@ -598,15 +598,15 @@ Command *VcsBaseClient::createCommand(const QString &workingDirectory,
d->bindCommandToEditor(cmd, editor);
if (mode == VcsWindowOutputBind) {
if (editor) { // assume that the commands output is the important thing
connect(cmd, SIGNAL(outputData(QByteArray)),
::vcsOutputWindow(), SLOT(appendDataSilently(QByteArray)));
connect(cmd, SIGNAL(outputData(QString)),
::vcsOutputWindow(), SLOT(appendSilently(QString)));
} else {
connect(cmd, SIGNAL(outputData(QByteArray)),
::vcsOutputWindow(), SLOT(appendData(QByteArray)));
connect(cmd, SIGNAL(outputData(QString)),
::vcsOutputWindow(), SLOT(append(QString)));
}
} else if (editor) {
connect(cmd, SIGNAL(outputData(QByteArray)),
editor, SLOT(setPlainTextData(QByteArray)));
connect(cmd, SIGNAL(outputData(QString)),
editor, SLOT(setPlainTextData(QString)));
}
if (::vcsOutputWindow())
......
......@@ -192,7 +192,7 @@ private:
friend class VcsBaseClientPrivate;
VcsBaseClientPrivate *d;
Q_PRIVATE_SLOT(d, void statusParser(QByteArray))
Q_PRIVATE_SLOT(d, void statusParser(QString))
Q_PRIVATE_SLOT(d, void annotateRevision(QString, QString, int))
Q_PRIVATE_SLOT(d, void saveSettings())
Q_PRIVATE_SLOT(d, void commandFinishedGotoLine(QWidget *))
......
......@@ -1169,12 +1169,12 @@ DiffChunk VcsBaseEditorWidget::diffChunk(QTextCursor cursor) const
return rc;
}
void VcsBaseEditorWidget::setPlainTextData(const QByteArray &data)
void VcsBaseEditorWidget::setPlainText(const QString &text)
{
if (data.size() > Core::EditorManager::maxTextFileSize())
setPlainText(msgTextTooLarge(data.size()));
if (text.size() > Core::EditorManager::maxTextFileSize())
TextEditor::BaseTextEditorWidget::setPlainText(msgTextTooLarge(text.size()));
else
setPlainText(codec()->toUnicode(data));
TextEditor::BaseTextEditorWidget::setPlainText(text);
}
void VcsBaseEditorWidget::reportCommandFinished(bool ok, int exitCode, const QVariant &data)
......
......@@ -205,7 +205,7 @@ signals:
public slots:
// Convenience slot to set data read from stdout, will use the
// documents' codec to decode
void setPlainTextData(const QByteArray &data);
void setPlainText(const QString &text);
void reportCommandFinished(bool ok, int exitCode, const QVariant &data);
protected:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment