summaryrefslogtreecommitdiffstats
path: root/examples/widgets/tools/codecs
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-08-05 08:58:48 +0200
committerLiang Qi <liang.qi@qt.io>2016-08-05 08:58:48 +0200
commit69ef0481fc22ec3f0d7fa220a47a27fecf76a710 (patch)
treef6d96cc257fcb27e12151f079c583251df4c4720 /examples/widgets/tools/codecs
parentdbfd7f304c4d91096e104ec2383d92a37502d836 (diff)
parent91a2c8630b2204831566ab8e523c747f9d8ec927 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp Change-Id: I6f3878b204464313aa2f9d988d3b35121d4d9867
Diffstat (limited to 'examples/widgets/tools/codecs')
-rw-r--r--examples/widgets/tools/codecs/mainwindow.cpp137
-rw-r--r--examples/widgets/tools/codecs/mainwindow.h16
-rw-r--r--examples/widgets/tools/codecs/previewform.cpp176
-rw-r--r--examples/widgets/tools/codecs/previewform.h16
4 files changed, 227 insertions, 118 deletions
diff --git a/examples/widgets/tools/codecs/mainwindow.cpp b/examples/widgets/tools/codecs/mainwindow.cpp
index fe29eeffa3..5e4810dd4d 100644
--- a/examples/widgets/tools/codecs/mainwindow.cpp
+++ b/examples/widgets/tools/codecs/mainwindow.cpp
@@ -55,8 +55,8 @@
MainWindow::MainWindow()
{
- textEdit = new QTextEdit;
- textEdit->setLineWrapMode(QTextEdit::NoWrap);
+ textEdit = new QPlainTextEdit;
+ textEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
setCentralWidget(textEdit);
findCodecs();
@@ -64,54 +64,57 @@ MainWindow::MainWindow()
previewForm = new PreviewForm(this);
previewForm->setCodecList(codecs);
- createActions();
createMenus();
setWindowTitle(tr("Codecs"));
- resize(500, 400);
+
+ const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
+ resize(screenGeometry.width() / 2, screenGeometry.height() * 2 / 3);
}
void MainWindow::open()
{
- QString fileName = QFileDialog::getOpenFileName(this);
- if (!fileName.isEmpty()) {
- QFile file(fileName);
- if (!file.open(QFile::ReadOnly)) {
- QMessageBox::warning(this, tr("Codecs"),
- tr("Cannot read file %1:\n%2")
- .arg(fileName)
- .arg(file.errorString()));
- return;
- }
+ const QString fileName = QFileDialog::getOpenFileName(this);
+ if (fileName.isEmpty())
+ return;
+ QFile file(fileName);
+ if (!file.open(QFile::ReadOnly)) {
+ QMessageBox::warning(this, tr("Codecs"),
+ tr("Cannot read file %1:\n%2")
+ .arg(QDir::toNativeSeparators(fileName),
+ file.errorString()));
+ return;
+ }
- QByteArray data = file.readAll();
+ const QByteArray data = file.readAll();
- previewForm->setEncodedData(data);
- if (previewForm->exec())
- textEdit->setPlainText(previewForm->decodedString());
- }
+ previewForm->setWindowTitle(tr("Choose Encoding for %1").arg(QFileInfo(fileName).fileName()));
+ previewForm->setEncodedData(data);
+ if (previewForm->exec())
+ textEdit->setPlainText(previewForm->decodedString());
}
void MainWindow::save()
{
- QString fileName = QFileDialog::getSaveFileName(this);
- if (!fileName.isEmpty()) {
- QFile file(fileName);
- if (!file.open(QFile::WriteOnly | QFile::Text)) {
- QMessageBox::warning(this, tr("Codecs"),
- tr("Cannot write file %1:\n%2")
- .arg(fileName)
- .arg(file.errorString()));
- return;
- }
-
- QAction *action = qobject_cast<QAction *>(sender());
- QByteArray codecName = action->data().toByteArray();
-
- QTextStream out(&file);
- out.setCodec(codecName.constData());
- out << textEdit->toPlainText();
+ const QAction *action = qobject_cast<const QAction *>(sender());
+ const QByteArray codecName = action->data().toByteArray();
+ const QString title = tr("Save As (%1)").arg(QLatin1String(codecName));
+
+ QString fileName = QFileDialog::getSaveFileName(this, title);
+ if (fileName.isEmpty())
+ return;
+ QFile file(fileName);
+ if (!file.open(QFile::WriteOnly | QFile::Text)) {
+ QMessageBox::warning(this, tr("Codecs"),
+ tr("Cannot write file %1:\n%2")
+ .arg(QDir::toNativeSeparators(fileName),
+ file.errorString()));
+ return;
}
+
+ QTextStream out(&file);
+ out.setCodec(codecName.constData());
+ out << textEdit->toPlainText();
}
void MainWindow::about()
@@ -143,9 +146,9 @@ void MainWindow::findCodecs()
QString sortKey = codec->name().toUpper();
int rank;
- if (sortKey.startsWith("UTF-8")) {
+ if (sortKey.startsWith(QLatin1String("UTF-8"))) {
rank = 1;
- } else if (sortKey.startsWith("UTF-16")) {
+ } else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
rank = 2;
} else if (iso8859RegExp.exactMatch(sortKey)) {
if (iso8859RegExp.cap(1).size() == 1)
@@ -155,58 +158,38 @@ void MainWindow::findCodecs()
} else {
rank = 5;
}
- sortKey.prepend(QChar('0' + rank));
+ sortKey.prepend(QLatin1Char('0' + rank));
codecMap.insert(sortKey, codec);
}
codecs = codecMap.values();
}
-void MainWindow::createActions()
+void MainWindow::createMenus()
{
- openAct = new QAction(tr("&Open..."), this);
+ QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+ QAction *openAct =
+ fileMenu->addAction(tr("&Open..."), this, &MainWindow::open);
openAct->setShortcuts(QKeySequence::Open);
- connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
-
- foreach (QTextCodec *codec, codecs) {
- QString text = tr("%1...").arg(QString(codec->name()));
- QAction *action = new QAction(text, this);
- action->setData(codec->name());
- connect(action, SIGNAL(triggered()), this, SLOT(save()));
+ QMenu *saveAsMenu = fileMenu->addMenu(tr("&Save As"));
+ connect(saveAsMenu, &QMenu::aboutToShow,
+ this, &MainWindow::aboutToShowSaveAsMenu);
+ foreach (const QTextCodec *codec, codecs) {
+ const QByteArray name = codec->name();
+ QAction *action = saveAsMenu->addAction(tr("%1...").arg(QLatin1String(name)));
+ action->setData(QVariant(name));
+ connect(action, &QAction::triggered, this, &MainWindow::save);
saveAsActs.append(action);
}
- exitAct = new QAction(tr("E&xit"), this);
- exitAct->setShortcuts(QKeySequence::Quit);
- connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
-
- aboutAct = new QAction(tr("&About"), this);
- connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
-
- aboutQtAct = new QAction(tr("About &Qt"), this);
- connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
-}
-
-void MainWindow::createMenus()
-{
- saveAsMenu = new QMenu(tr("&Save As"), this);
- foreach (QAction *action, saveAsActs)
- saveAsMenu->addAction(action);
- connect(saveAsMenu, SIGNAL(aboutToShow()),
- this, SLOT(aboutToShowSaveAsMenu()));
-
- fileMenu = new QMenu(tr("&File"), this);
- fileMenu->addAction(openAct);
- fileMenu->addMenu(saveAsMenu);
fileMenu->addSeparator();
- fileMenu->addAction(exitAct);
-
- helpMenu = new QMenu(tr("&Help"), this);
- helpMenu->addAction(aboutAct);
- helpMenu->addAction(aboutQtAct);
+ QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
+ exitAct->setShortcuts(QKeySequence::Quit);
- menuBar()->addMenu(fileMenu);
menuBar()->addSeparator();
- menuBar()->addMenu(helpMenu);
+
+ QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+ helpMenu->addAction(tr("&About"), this, &MainWindow::about);
+ helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
}
diff --git a/examples/widgets/tools/codecs/mainwindow.h b/examples/widgets/tools/codecs/mainwindow.h
index 1e8b440a02..7121c0b122 100644
--- a/examples/widgets/tools/codecs/mainwindow.h
+++ b/examples/widgets/tools/codecs/mainwindow.h
@@ -56,9 +56,8 @@
QT_BEGIN_NAMESPACE
class QAction;
-class QMenu;
class QTextCodec;
-class QTextEdit;
+class QPlainTextEdit;
QT_END_NAMESPACE
class PreviewForm;
@@ -77,21 +76,12 @@ private slots:
private:
void findCodecs();
- void createActions();
void createMenus();
- QTextEdit *textEdit;
+ QList<QAction *> saveAsActs;
+ QPlainTextEdit *textEdit;
PreviewForm *previewForm;
QList<QTextCodec *> codecs;
-
- QMenu *fileMenu;
- QMenu *helpMenu;
- QMenu *saveAsMenu;
- QAction *openAct;
- QList<QAction *> saveAsActs;
- QAction *exitAct;
- QAction *aboutAct;
- QAction *aboutQtAct;
};
#endif
diff --git a/examples/widgets/tools/codecs/previewform.cpp b/examples/widgets/tools/codecs/previewform.cpp
index 82203175ca..e5ca13f011 100644
--- a/examples/widgets/tools/codecs/previewform.cpp
+++ b/examples/widgets/tools/codecs/previewform.cpp
@@ -52,47 +52,159 @@
#include "previewform.h"
+// Helpers for creating hex dumps
+static void indent(QTextStream &str, int indent)
+{
+ for (int i = 0; i < indent; ++i)
+ str << ' ';
+}
+
+static void formatHex(QTextStream &str, const QByteArray &data)
+{
+ const int fieldWidth = str.fieldWidth();
+ const QTextStream::FieldAlignment alignment = str.fieldAlignment();
+ const int base = str.integerBase();
+ const QChar padChar = str.padChar();
+ str.setIntegerBase(16);
+ str.setPadChar(QLatin1Char('0'));
+ str.setFieldAlignment(QTextStream::AlignRight);
+
+ const unsigned char *p = reinterpret_cast<const unsigned char *>(data.constBegin());
+ for (const unsigned char *end = p + data.size(); p < end; ++p) {
+ str << ' ';
+ str.setFieldWidth(2);
+ str << unsigned(*p);
+ str.setFieldWidth(fieldWidth);
+ }
+ str.setFieldAlignment(alignment);
+ str.setPadChar(padChar);
+ str.setIntegerBase(base);
+}
+
+static void formatPrintableCharacters(QTextStream &str, const QByteArray &data)
+{
+ for (int i = 0, size = data.size(); i < size; ++i) {
+ const char c = data.at(i);
+ switch (c) {
+ case '\0':
+ str << "\\0";
+ break;
+ case '\t':
+ str << "\\t";
+ break;
+ case '\r':
+ str << "\\r";
+ break;
+ case '\n':
+ str << "\\n";
+ break;
+ default:
+ if (c >= 32 && uchar(c) < 127)
+ str << ' ' << c;
+ else
+ str << "..";
+ break;
+ }
+ }
+}
+
+static QString formatHexDump(const QByteArray &data)
+{
+ enum { lineWidth = 16 };
+ QString result;
+ QTextStream str(&result);
+ str.setIntegerBase(16);
+ str.setPadChar(QLatin1Char('0'));
+ const int fieldWidth = str.fieldWidth();
+ const QTextStream::FieldAlignment alignment = str.fieldAlignment();
+ for (int a = 0, size = data.size(); a < size; a += lineWidth) {
+ str.setFieldAlignment(QTextStream::AlignRight);
+ str.setFieldWidth(8);
+ str << a;
+ str.setFieldWidth(fieldWidth);
+ str.setFieldAlignment(alignment);
+
+ const int end = qMin(a + lineWidth, size);
+ const QByteArray line = data.mid(a, end - a);
+
+ formatHex(str, line);
+ indent(str, 3 * (lineWidth - line.size()));
+
+ str << ' ';
+ formatPrintableCharacters(str, line);
+ indent(str, 2 * (lineWidth - line.size()));
+ str << '\n';
+ }
+ return result;
+}
+
PreviewForm::PreviewForm(QWidget *parent)
: QDialog(parent)
{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
encodingComboBox = new QComboBox;
- encodingLabel = new QLabel(tr("&Encoding:"));
+ QLabel *encodingLabel = new QLabel(tr("&Encoding:"));
encodingLabel->setBuddy(encodingComboBox);
- textEdit = new QTextEdit;
- textEdit->setLineWrapMode(QTextEdit::NoWrap);
+ textEdit = new QPlainTextEdit;
+ textEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
textEdit->setReadOnly(true);
+ hexDumpEdit = new QPlainTextEdit;
+ hexDumpEdit->setLineWrapMode(QPlainTextEdit::NoWrap);
+ hexDumpEdit->setReadOnly(true);
+ hexDumpEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
- buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
- | QDialogButtonBox::Cancel);
+ QDialogButtonBox *buttonBox =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ okButton = buttonBox->button(QDialogButtonBox::Ok);
- connect(encodingComboBox, SIGNAL(activated(int)),
- this, SLOT(updateTextEdit()));
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ typedef void(QComboBox::*ComboBoxIntSignal)(int);
+ connect(encodingComboBox, static_cast<ComboBoxIntSignal>(&QComboBox::activated),
+ this, &PreviewForm::updateTextEdit);
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
- QGridLayout *mainLayout = new QGridLayout;
+ QGridLayout *mainLayout = new QGridLayout(this);
mainLayout->addWidget(encodingLabel, 0, 0);
mainLayout->addWidget(encodingComboBox, 0, 1);
- mainLayout->addWidget(textEdit, 1, 0, 1, 2);
- mainLayout->addWidget(buttonBox, 2, 0, 1, 2);
- setLayout(mainLayout);
+ tabWidget = new QTabWidget;
+ tabWidget->addTab(textEdit, tr("Preview"));
+ tabWidget->addTab(hexDumpEdit, tr("Hex Dump"));
+ mainLayout->addWidget(tabWidget, 1, 0, 1, 2);
+ statusLabel = new QLabel;
+ mainLayout->addWidget(statusLabel, 2, 0, 1, 2);
+ mainLayout->addWidget(buttonBox, 3, 0, 1, 2);
- setWindowTitle(tr("Choose Encoding"));
- resize(400, 300);
+ const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
+ resize(screenGeometry.width() * 2 / 5, screenGeometry.height() / 2);
}
void PreviewForm::setCodecList(const QList<QTextCodec *> &list)
{
encodingComboBox->clear();
- foreach (QTextCodec *codec, list)
- encodingComboBox->addItem(codec->name(), codec->mibEnum());
+ foreach (const QTextCodec *codec, list) {
+ encodingComboBox->addItem(QLatin1String(codec->name()),
+ QVariant(codec->mibEnum()));
+ }
+}
+
+void PreviewForm::reset()
+{
+ decodedStr.clear();
+ textEdit->clear();
+ hexDumpEdit->clear();
+ statusLabel->clear();
+ statusLabel->setStyleSheet(QString());
+ okButton->setEnabled(false);
+ tabWidget->setCurrentIndex(0);
}
void PreviewForm::setEncodedData(const QByteArray &data)
{
+ reset();
encodedData = data;
+ hexDumpEdit->setPlainText(formatHexDump(data));
updateTextEdit();
}
@@ -100,12 +212,30 @@ void PreviewForm::updateTextEdit()
{
int mib = encodingComboBox->itemData(
encodingComboBox->currentIndex()).toInt();
- QTextCodec *codec = QTextCodec::codecForMib(mib);
+ const QTextCodec *codec = QTextCodec::codecForMib(mib);
+ const QString name = QLatin1String(codec->name());
- QTextStream in(&encodedData);
- in.setAutoDetectUnicode(false);
- in.setCodec(codec);
- decodedStr = in.readAll();
+ QTextCodec::ConverterState state;
+ decodedStr = codec->toUnicode(encodedData.constData(), encodedData.size(), &state);
- textEdit->setPlainText(decodedStr);
+ bool success = true;
+ if (state.remainingChars) {
+ success = false;
+ const QString message =
+ tr("%1: conversion error at character %2")
+ .arg(name).arg(encodedData.size() - state.remainingChars + 1);
+ statusLabel->setText(message);
+ statusLabel->setStyleSheet(QStringLiteral("background-color: \"red\";"));
+ } else if (state.invalidChars) {
+ statusLabel->setText(tr("%1: %n invalid characters", 0, state.invalidChars).arg(name));
+ statusLabel->setStyleSheet(QStringLiteral("background-color: \"yellow\";"));
+ } else {
+ statusLabel->setText(tr("%1: %n bytes converted", 0, encodedData.size()).arg(name));
+ statusLabel->setStyleSheet(QString());
+ }
+ if (success)
+ textEdit->setPlainText(decodedStr);
+ else
+ textEdit->clear();
+ okButton->setEnabled(success);
}
diff --git a/examples/widgets/tools/codecs/previewform.h b/examples/widgets/tools/codecs/previewform.h
index f3e13233b4..1846b976de 100644
--- a/examples/widgets/tools/codecs/previewform.h
+++ b/examples/widgets/tools/codecs/previewform.h
@@ -58,8 +58,10 @@ QT_BEGIN_NAMESPACE
class QComboBox;
class QDialogButtonBox;
class QLabel;
+class QPlainTextEdit;
+class QPushButton;
+class QTabWidget;
class QTextCodec;
-class QTextEdit;
QT_END_NAMESPACE
class PreviewForm : public QDialog
@@ -67,7 +69,7 @@ class PreviewForm : public QDialog
Q_OBJECT
public:
- PreviewForm(QWidget *parent = 0);
+ explicit PreviewForm(QWidget *parent = Q_NULLPTR);
void setCodecList(const QList<QTextCodec *> &list);
void setEncodedData(const QByteArray &data);
@@ -77,13 +79,17 @@ private slots:
void updateTextEdit();
private:
+ void reset();
+
QByteArray encodedData;
QString decodedStr;
+ QPushButton *okButton;
+ QTabWidget *tabWidget;
QComboBox *encodingComboBox;
- QLabel *encodingLabel;
- QTextEdit *textEdit;
- QDialogButtonBox *buttonBox;
+ QPlainTextEdit *textEdit;
+ QPlainTextEdit *hexDumpEdit;
+ QLabel *statusLabel;
};
#endif