forked from qt-creator/qt-creator
DiffEditor: add info bar for documents with encoding errors
... with the option to reload the diff document with another encoding. Fixes: QTCREATORBUG-23835 Change-Id: I1ce07b292688059b37535f2972970d8ea91be81b Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -38,6 +38,7 @@ const char DIFF_EDITOR_MIMETYPE[] = "text/x-patch";
|
|||||||
const char C_DIFF_EDITOR_DESCRIPTION[] = "DiffEditor.Description";
|
const char C_DIFF_EDITOR_DESCRIPTION[] = "DiffEditor.Description";
|
||||||
const char SIDE_BY_SIDE_VIEW_ID[] = "DiffEditor.SideBySide";
|
const char SIDE_BY_SIDE_VIEW_ID[] = "DiffEditor.SideBySide";
|
||||||
const char UNIFIED_VIEW_ID[] = "DiffEditor.Unified";
|
const char UNIFIED_VIEW_ID[] = "DiffEditor.Unified";
|
||||||
|
const char SELECT_ENCODING[] = "DiffEditor.SelectEncoding";
|
||||||
|
|
||||||
const char G_TOOLS_DIFF[] = "QtCreator.Group.Tools.Options";
|
const char G_TOOLS_DIFF[] = "QtCreator.Group.Tools.Options";
|
||||||
|
|
||||||
|
@@ -31,7 +31,9 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <coreplugin/dialogs/codecselector.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@@ -314,10 +316,10 @@ Core::IDocument::OpenResult DiffEditorDocument::open(QString *errorString, const
|
|||||||
beginReload();
|
beginReload();
|
||||||
QString patch;
|
QString patch;
|
||||||
ReadResult readResult = read(fileName, &patch, errorString);
|
ReadResult readResult = read(fileName, &patch, errorString);
|
||||||
if (readResult == TextFileFormat::ReadEncodingError)
|
if (readResult == TextFileFormat::ReadIOError
|
||||||
return OpenResult::CannotHandle;
|
|| readResult == TextFileFormat::ReadMemoryAllocationError) {
|
||||||
else if (readResult != TextFileFormat::ReadSuccess)
|
|
||||||
return OpenResult::ReadError;
|
return OpenResult::ReadError;
|
||||||
|
}
|
||||||
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
QList<FileData> fileDataList = DiffUtils::readPatch(patch, &ok);
|
QList<FileData> fileDataList = DiffUtils::readPatch(patch, &ok);
|
||||||
@@ -333,9 +335,29 @@ Core::IDocument::OpenResult DiffEditorDocument::open(QString *errorString, const
|
|||||||
setDiffFiles(fileDataList, fi.absolutePath());
|
setDiffFiles(fileDataList, fi.absolutePath());
|
||||||
}
|
}
|
||||||
endReload(ok);
|
endReload(ok);
|
||||||
|
if (!ok && readResult == TextFileFormat::ReadEncodingError)
|
||||||
|
ok = selectEncoding();
|
||||||
return ok ? OpenResult::Success : OpenResult::CannotHandle;
|
return ok ? OpenResult::Success : OpenResult::CannotHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DiffEditorDocument::selectEncoding()
|
||||||
|
{
|
||||||
|
Core::CodecSelector codecSelector(Core::ICore::dialogParent(), this);
|
||||||
|
switch (codecSelector.exec()) {
|
||||||
|
case Core::CodecSelector::Reload: {
|
||||||
|
setCodec(codecSelector.selectedCodec());
|
||||||
|
QString errorMessage;
|
||||||
|
return reload(&errorMessage, Core::IDocument::FlagReload, Core::IDocument::TypeContents);
|
||||||
|
}
|
||||||
|
case Core::CodecSelector::Save:
|
||||||
|
setCodec(codecSelector.selectedCodec());
|
||||||
|
return Core::EditorManager::saveDocument(this);
|
||||||
|
case Core::CodecSelector::Cancel:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString DiffEditorDocument::fallbackSaveAsFileName() const
|
QString DiffEditorDocument::fallbackSaveAsFileName() const
|
||||||
{
|
{
|
||||||
const int maxSubjectLength = 50;
|
const int maxSubjectLength = 50;
|
||||||
|
@@ -86,6 +86,7 @@ public:
|
|||||||
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
|
bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
|
||||||
OpenResult open(QString *errorString, const QString &fileName,
|
OpenResult open(QString *errorString, const QString &fileName,
|
||||||
const QString &realFileName) override;
|
const QString &realFileName) override;
|
||||||
|
bool selectEncoding();
|
||||||
State state() const { return m_state; }
|
State state() const { return m_state; }
|
||||||
|
|
||||||
QString plainText() const;
|
QString plainText() const;
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <coreplugin/infobar.h>
|
||||||
#include <coreplugin/patchtool.h>
|
#include <coreplugin/patchtool.h>
|
||||||
|
|
||||||
#include <texteditor/fontsettings.h>
|
#include <texteditor/fontsettings.h>
|
||||||
@@ -76,7 +77,7 @@ void DiffEditorWidgetController::setDocument(DiffEditorDocument *document)
|
|||||||
|
|
||||||
if (m_document) {
|
if (m_document) {
|
||||||
disconnect(m_document, &IDocument::aboutToReload, this, &DiffEditorWidgetController::scheduleShowProgress);
|
disconnect(m_document, &IDocument::aboutToReload, this, &DiffEditorWidgetController::scheduleShowProgress);
|
||||||
disconnect(m_document, &IDocument::reloadFinished, this, &DiffEditorWidgetController::hideProgress);
|
disconnect(m_document, &IDocument::reloadFinished, this, &DiffEditorWidgetController::onDocumentReloadFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool wasRunning = m_document && m_document->state() == DiffEditorDocument::Reloading;
|
const bool wasRunning = m_document && m_document->state() == DiffEditorDocument::Reloading;
|
||||||
@@ -85,7 +86,8 @@ void DiffEditorWidgetController::setDocument(DiffEditorDocument *document)
|
|||||||
|
|
||||||
if (m_document) {
|
if (m_document) {
|
||||||
connect(m_document, &IDocument::aboutToReload, this, &DiffEditorWidgetController::scheduleShowProgress);
|
connect(m_document, &IDocument::aboutToReload, this, &DiffEditorWidgetController::scheduleShowProgress);
|
||||||
connect(m_document, &IDocument::reloadFinished, this, &DiffEditorWidgetController::hideProgress);
|
connect(m_document, &IDocument::reloadFinished, this, &DiffEditorWidgetController::onDocumentReloadFinished);
|
||||||
|
updateCannotDecodeInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isRunning = m_document && m_document->state() == DiffEditorDocument::Reloading;
|
const bool isRunning = m_document && m_document->state() == DiffEditorDocument::Reloading;
|
||||||
@@ -123,6 +125,12 @@ void DiffEditorWidgetController::hideProgress()
|
|||||||
m_progressIndicator->hide();
|
m_progressIndicator->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiffEditorWidgetController::onDocumentReloadFinished()
|
||||||
|
{
|
||||||
|
updateCannotDecodeInfo();
|
||||||
|
hideProgress();
|
||||||
|
}
|
||||||
|
|
||||||
void DiffEditorWidgetController::patch(bool revert, int fileIndex, int chunkIndex)
|
void DiffEditorWidgetController::patch(bool revert, int fileIndex, int chunkIndex)
|
||||||
{
|
{
|
||||||
if (!m_document)
|
if (!m_document)
|
||||||
@@ -294,6 +302,27 @@ void DiffEditorWidgetController::addExtraActions(QMenu *menu, int fileIndex, int
|
|||||||
controller->requestChunkActions(menu, fileIndex, chunkIndex, selection);
|
controller->requestChunkActions(menu, fileIndex, chunkIndex, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiffEditorWidgetController::updateCannotDecodeInfo()
|
||||||
|
{
|
||||||
|
if (!m_document)
|
||||||
|
return;
|
||||||
|
|
||||||
|
InfoBar *infoBar = m_document->infoBar();
|
||||||
|
Id selectEncodingId(Constants::SELECT_ENCODING);
|
||||||
|
if (m_document->hasDecodingError()) {
|
||||||
|
if (!infoBar->canInfoBeAdded(selectEncodingId))
|
||||||
|
return;
|
||||||
|
InfoBarEntry info(selectEncodingId,
|
||||||
|
tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding.")
|
||||||
|
.arg(m_document->displayName(),
|
||||||
|
QString::fromLatin1(m_document->codec()->name())));
|
||||||
|
info.setCustomButtonInfo(tr("Select Encoding"), [this]() { m_document->selectEncoding(); });
|
||||||
|
infoBar->addInfo(info);
|
||||||
|
} else {
|
||||||
|
infoBar->removeInfo(selectEncodingId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DiffEditorWidgetController::sendChunkToCodePaster(int fileIndex, int chunkIndex)
|
void DiffEditorWidgetController::sendChunkToCodePaster(int fileIndex, int chunkIndex)
|
||||||
{
|
{
|
||||||
if (!m_document)
|
if (!m_document)
|
||||||
|
@@ -61,6 +61,7 @@ public:
|
|||||||
void addApplyAction(QMenu *menu, int fileIndex, int chunkIndex);
|
void addApplyAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||||
void addRevertAction(QMenu *menu, int fileIndex, int chunkIndex);
|
void addRevertAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||||
void addExtraActions(QMenu *menu, int fileIndex, int chunkIndex, const ChunkSelection &selection);
|
void addExtraActions(QMenu *menu, int fileIndex, int chunkIndex, const ChunkSelection &selection);
|
||||||
|
void updateCannotDecodeInfo();
|
||||||
|
|
||||||
ChunkData chunkData(int fileIndex, int chunkIndex) const;
|
ChunkData chunkData(int fileIndex, int chunkIndex) const;
|
||||||
|
|
||||||
@@ -83,6 +84,7 @@ private:
|
|||||||
void scheduleShowProgress();
|
void scheduleShowProgress();
|
||||||
void showProgress();
|
void showProgress();
|
||||||
void hideProgress();
|
void hideProgress();
|
||||||
|
void onDocumentReloadFinished();
|
||||||
|
|
||||||
QWidget *m_diffEditorWidget = nullptr;
|
QWidget *m_diffEditorWidget = nullptr;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user