|
From: Tapio V. <aa...@us...> - 2011-01-26 07:14:16
|
Module: editor
Branch: master
Commit: 93e11e258aeb76d55645245e667fd0abb42d5a09
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jan 26 09:12:50 2011 +0200
Add a codec selector dialog when wrong encoding is detected.
The "Automatic" option doesn't seem to work. :-(
---
CMakeLists.txt | 2 +-
songparser.cc | 19 +++++++---
textcodecselector.hh | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+), 6 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5a286f4..6d20b5f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,7 +42,7 @@ else(Phonon_FOUND)
endif(Phonon_FOUND)
# Headers that need MOC need to be defined separately
-file(GLOB MOC_HEADER_FILES "editorapp.hh" "notelabel.hh" "notegraphwidget.hh")
+file(GLOB MOC_HEADER_FILES "editorapp.hh" "notelabel.hh" "notegraphwidget.hh" "textcodecselector.hh")
file(GLOB SOURCE_FILES "*.cc")
file(GLOB HEADER_FILES "*.hh")
diff --git a/songparser.cc b/songparser.cc
index bf2bc9b..c917154 100644
--- a/songparser.cc
+++ b/songparser.cc
@@ -1,5 +1,5 @@
#include "songparser.hh"
-
+#include "textcodecselector.hh"
#include <QFile>
#include <QFileInfo>
@@ -37,12 +37,21 @@ SongParser::SongParser(Song& s):
QFileInfo finfo(file);
if (finfo.size() < 10 || finfo.size() > 100000) throw SongParserException("Does not look like a song file (wrong size)", 1, true);
- QTextStream stream(&file);
- QString data = stream.readAll();
+ // Determine encoding
+ QString data;
+ {
+ QByteArray ba = file.readAll();
+ if (!ba.isEmpty()) {
+ data = QString::fromLocal8Bit(ba, ba.size());
+ if (data.toLocal8Bit().size() != ba.size()) {
+ // Not UTF8 :(
+ QTextCodec* codec = TextCodecSelector::codecForContent(ba);
+ if (codec) data = codec->toUnicode(ba);
+ }
+ }
+ }
file.close();
- // TODO: Convert data from unknown encoding
-
if (smCheck(data)) type = SM;
else if (txtCheck(data)) type = TXT;
else if (xmlCheck(data)) type = XML;
diff --git a/textcodecselector.hh b/textcodecselector.hh
new file mode 100644
index 0000000..225a332
--- /dev/null
+++ b/textcodecselector.hh
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2000-2008 TROLLTECH ASA. All rights reserved.
+**
+** This file is part of the Opensource Edition of the Qtopia Toolkit.
+**
+** This software is licensed under the terms of the GNU General Public
+** License (GPL) version 2.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact in...@tr... if any conditions of this licensing are
+** not clear to you.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** Code has been modified from the original.
+****************************************************************************/
+
+#include <QDialog>
+#include <QWidget>
+#include <QListWidget>
+#include <QTextCodec>
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QByteArray>
+
+#include <iostream>
+
+class TextCodecSelector : public QDialog {
+ Q_OBJECT
+public:
+ TextCodecSelector(QWidget* parent = 0)
+ : QDialog(parent)
+ {
+ setWindowTitle(tr("Unknown encoding"));
+ list = new QListWidget(this);
+ connect(list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(accept()));
+ connect(list, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(accept()));
+ codecs = QTextCodec::availableCodecs();
+ qSort(codecs);
+ list->addItem(tr("Automatic"));
+ foreach (QByteArray n, codecs) {
+ list->addItem(n);
+ }
+ QLabel *label = new QLabel(tr("<qt>Choose the encoding for this file:</qt>"));
+ label->setWordWrap(true);
+ QVBoxLayout *vb = new QVBoxLayout(this);
+ vb->addWidget(label);
+ vb->addWidget(list);
+ setLayout(vb);
+ }
+
+ QTextCodec *selection(QByteArray ba) const
+ {
+ int n = list->currentRow();
+ if (n < 0) {
+ return 0;
+ } else if (n == 0) {
+ // Automatic... just try them all and pick the one that can convert
+ // in and out without losing anything with the smallest intermediate length.
+ QTextCodec *best = 0;
+ int shortest = INT_MAX;
+ foreach (QByteArray name, codecs) {
+ QTextCodec* c = QTextCodec::codecForName(name);
+ QString enc = c->toUnicode(ba);
+ if (c->fromUnicode(enc) == ba) {
+ std::cout << QString(c->name()).toStdString() << std::endl;
+ if (enc.length() < shortest) {
+ best = c;
+ shortest = enc.length();
+ }
+ }
+ }
+ return best;
+ } else {
+ return QTextCodec::codecForName(codecs.at(n-1));
+ }
+ }
+
+ static QTextCodec* codecForContent(QByteArray ba, QWidget *parent = 0)
+ {
+ TextCodecSelector tcs(parent);
+ tcs.setModal(true);
+ tcs.exec();
+ if (tcs.result())
+ return tcs.selection(ba);
+ return 0;
+ }
+
+private:
+ QListWidget *list;
+ QList<QByteArray> codecs;
+};
|