summaryrefslogtreecommitdiff
path: root/src/plugins/texteditor/codecselector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/texteditor/codecselector.cpp')
-rw-r--r--src/plugins/texteditor/codecselector.cpp179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/plugins/texteditor/codecselector.cpp b/src/plugins/texteditor/codecselector.cpp
new file mode 100644
index 0000000000..5893fa5b71
--- /dev/null
+++ b/src/plugins/texteditor/codecselector.cpp
@@ -0,0 +1,179 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "codecselector.h"
+#include "basetextdocument.h"
+
+
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextCodec>
+#include <QtGui/QPushButton>
+#include <QtGui/QScrollBar>
+#include <QtGui/QVBoxLayout>
+
+using namespace TextEditor;
+using namespace TextEditor::Internal;
+
+
+namespace TextEditor {
+ namespace Internal {
+
+ /* custom class to make sure the width is wide enough for the
+ * contents. Should be easier with Qt. */
+ class CodecListWidget : public QListWidget {
+ public:
+ CodecListWidget(QWidget *parent):QListWidget(parent){}
+ QSize sizeHint() const {
+ return QListWidget::sizeHint().expandedTo(
+ QSize(sizeHintForColumn(0) + verticalScrollBar()->sizeHint().width() + 4, 0));
+ }
+ };
+ }
+}
+
+CodecSelector::CodecSelector(QWidget *parent, BaseTextDocument *doc)
+ : QDialog(parent)
+{
+ m_hasDecodingError = doc->hasDecodingError();
+ m_isModified = doc->isModified();
+
+ QByteArray buf;
+ if (m_hasDecodingError)
+ buf = doc->decodingErrorSample();
+
+ setWindowTitle(tr("Text Encoding"));
+ m_label = new QLabel(this);
+ QString decodingErrorHint;
+ if (m_hasDecodingError)
+ decodingErrorHint = tr("\nThe following encodings are likely to fit:");
+ m_label->setText(tr("Select encoding for \"%1\".%2").arg(QFileInfo(doc->fileName()).fileName()).arg(decodingErrorHint));
+
+ m_listWidget = new CodecListWidget(this);
+
+ QStringList encodings;
+
+ QList<int> mibs = QTextCodec::availableMibs();
+ qSort(mibs);
+ QList<int> sortedMibs;
+ foreach(int mib, mibs)
+ if (mib >= 0)
+ sortedMibs += mib;
+ foreach(int mib, mibs)
+ if (mib < 0)
+ sortedMibs += mib;
+
+ int currentIndex = -1;
+ foreach(int mib, sortedMibs) {
+ QTextCodec *c = QTextCodec::codecForMib(mib);
+ if (!buf.isEmpty()) {
+
+ // slow, should use a feature from QTextCodec or QTextDecoder (but those are broken currently)
+ QByteArray verifyBuf = c->fromUnicode(c->toUnicode(buf));
+ // the minSize trick lets us ignore unicode headers
+ int minSize = qMin(verifyBuf.size(), buf.size());
+ if (minSize < buf.size() - 4
+ || memcmp(verifyBuf.constData() + verifyBuf.size() - minSize,
+ buf.constData() + buf.size() - minSize, minSize))
+ continue;
+ }
+ QString names = QString::fromLatin1(c->name());
+ foreach(QByteArray alias, c->aliases()) {
+ names += QLatin1String(" / ") + QString::fromLatin1(alias);
+ }
+ if (doc->codec() == c)
+ currentIndex = encodings.count();
+ encodings << names;
+ }
+ m_listWidget->addItems(encodings);
+ if (currentIndex >= 0)
+ m_listWidget->setCurrentRow(currentIndex);
+
+ connect(m_listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons()));
+
+ m_dialogButtonBox = new QDialogButtonBox(this);
+ m_reloadButton = m_dialogButtonBox->addButton(tr("Reload with Encoding"), QDialogButtonBox::DestructiveRole);
+ m_saveButton = m_dialogButtonBox->addButton(tr("Save with Encoding"), QDialogButtonBox::DestructiveRole);
+ m_dialogButtonBox->addButton(QDialogButtonBox::Cancel);
+ connect(m_dialogButtonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));
+
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ vbox->addWidget(m_label);
+ vbox->addWidget(m_listWidget);
+ vbox->addWidget(m_dialogButtonBox);
+
+ updateButtons();
+}
+
+
+
+CodecSelector::~CodecSelector()
+{
+}
+
+void CodecSelector::updateButtons()
+{
+ bool hasCodec = (selectedCodec() != 0);
+ m_reloadButton->setEnabled(!m_isModified && hasCodec);
+ m_saveButton->setEnabled(!m_hasDecodingError && hasCodec);
+}
+
+QTextCodec *CodecSelector::selectedCodec() const
+{
+ if (QListWidgetItem *item = m_listWidget->currentItem()) {
+ if (!item->isSelected())
+ return 0;
+ QString codecName = item->text();
+ if (codecName.contains(QLatin1String(" / ")))
+ codecName = codecName.left(codecName.indexOf(QLatin1String(" / ")));
+ return QTextCodec::codecForName(codecName.toLatin1());
+ }
+ return 0;
+}
+
+
+CodecSelector::Result CodecSelector::exec()
+{
+ return (Result) QDialog::exec();
+}
+
+
+void CodecSelector::buttonClicked(QAbstractButton *button)
+{
+ Result result = Cancel;
+ if (button == m_reloadButton)
+ result = Reload;
+ if (button == m_saveButton)
+ result = Save;
+ done(result);
+}
+