2 #include "simpletextview.h"
3 #include "mainwindow.h"
12 QString KeyEventToSequence(const QKeyEvent *event)
14 QString modifier = QString::null;
15 if (event->modifiers() & Qt::ShiftModifier) { modifier += "Shift+"; }
16 if (event->modifiers() & Qt::ControlModifier) { modifier += "Ctrl+"; }
17 if (event->modifiers() & Qt::AltModifier) { modifier += "Alt+"; }
18 if (event->modifiers() & Qt::MetaModifier) { modifier += "Meta+"; }
20 QString key = QKeySequence(event->key()).toString();
21 return QKeySequence(modifier + key).toString();
24 SimpleTextView::SimpleTextView(QWidget *parent) :
25 QPlainTextEdit(parent),
38 setContextMenuPolicy(Qt::DefaultContextMenu);
39 m_convEUC = new QAction(tr("EUC-JPで再読込"), this);
40 m_convJIS = new QAction(tr("ISO 2022-JP(JIS)で再読込"), this);
41 m_convSJIS = new QAction(tr("Shift-JISで再読込"), this);
42 m_convUTF8 = new QAction(tr("UTF-8で再読込"), this);
43 m_convUTF16 = new QAction(tr("UTF-16で再読込"), this);
44 m_convUTF16BE = new QAction(tr("UTF-16BEで再読込"), this);
45 m_convUTF16LE = new QAction(tr("UTF-16LEで再読込"), this);
46 m_copy = new QAction(tr("選択範囲をクリップボードにコピー"), this);
47 m_back = new QAction(tr("戻る"), this);
49 m_convEUC->setObjectName("convertFromEUC");
50 m_convJIS->setObjectName("convertFromJIS");
51 m_convSJIS->setObjectName("convertFromSJIS");
52 m_convUTF8->setObjectName("convertFromUTF8");
53 m_convUTF16->setObjectName("convertFromUTF16");
54 m_convUTF16BE->setObjectName("convertFromUTF16BE");
55 m_convUTF16LE->setObjectName("convertFromUTF16LE");
56 m_copy->setObjectName("copy");
57 m_back->setObjectName("back");
59 m_convEUC->setShortcut(QKeySequence("Shift+E"));
60 m_convJIS->setShortcut(QKeySequence("Shift+J"));
61 m_convSJIS->setShortcut(QKeySequence("Shift+S"));
62 m_convUTF8->setShortcut(QKeySequence("Shift+U"));
63 m_convUTF16->setShortcut(QKeySequence("Shift+I"));
64 m_convUTF16BE->setShortcut(QKeySequence("Shift+O"));
65 m_convUTF16LE->setShortcut(QKeySequence("Shift+P"));
66 m_copy->setShortcut(QKeySequence::Copy);
67 m_back->setShortcut(QKeySequence("Return"));
69 QList<QKeySequence> shortcuts;
70 shortcuts = m_back->shortcuts();
71 shortcuts.append(QKeySequence("Backspace"));
72 m_back->setShortcuts(shortcuts);
74 connect(m_convEUC, SIGNAL(triggered()), this, SLOT(convertFromEUC()));
75 connect(m_convJIS, SIGNAL(triggered()), this, SLOT(convertFromJIS()));
76 connect(m_convSJIS, SIGNAL(triggered()), this, SLOT(convertFromSJIS()));
77 connect(m_convUTF8, SIGNAL(triggered()), this, SLOT(convertFromUTF8()));
78 connect(m_convUTF16, SIGNAL(triggered()), this, SLOT(convertFromUTF16()));
79 connect(m_convUTF16BE, SIGNAL(triggered()), this, SLOT(convertFromUTF16BE()));
80 connect(m_convUTF16LE, SIGNAL(triggered()), this, SLOT(convertFromUTF16LE()));
81 connect(m_copy, SIGNAL(triggered()), this, SLOT(copy()));
82 connect(m_back, SIGNAL(triggered()), this, SLOT(back()));
84 connect(this, SIGNAL(copyAvailable(bool)), this, SLOT(onCopyAvailable(bool)));
86 m_copy->setEnabled(false);
89 void SimpleTextView::setSource(const QByteArray &source)
94 const char UTF8_BOM[] = { 0xEF, 0xBB, 0xBF };
95 const char UTF16BE_BOM[] = { 0xFE, 0xFF };
96 const char UTF16LE_BOM[] = { 0xFF, 0xFE };
98 if (m_source.indexOf(QByteArray(UTF8_BOM)) == 0) {
99 qDebug() << "Detect UTF-8 BOM";
102 else if (m_source.indexOf(QByteArray(UTF16BE_BOM)) == 0 ||
103 m_source.indexOf(QByteArray(UTF16LE_BOM)) == 0)
105 qDebug() << "Detect UTF-16 BOM";
109 QByteArray first1KB = m_source.left(1024);
111 QTextCodec *codec = QTextCodec::codecForName("UTF-8");
112 QString text = codec->toUnicode(first1KB).toLower();
113 if (text.indexOf("utf8") != -1 || text.indexOf("utf-8") != -1) {
117 if (text.indexOf("sjis") != -1 || text.indexOf("shift-jis") != -1 ||
118 text.indexOf("shift_jis") != -1)
123 if (text.indexOf("euc") != -1 || text.indexOf("euc-jp") != -1 ||
124 text.indexOf("euc_jp") != -1)
129 if (text.indexOf("jis") != -1 || text.indexOf("iso 2022-jp") != -1) {
134 std::string code = detectCode(first1KB);
135 codec = QTextCodec::codecForName(code.c_str());
136 setPlainText(codec->toUnicode(m_source));
137 getMainWnd()->statusBar()->showMessage(code.c_str());
140 void SimpleTextView::updateAppearance()
144 QPalette pal = this->palette();
145 if (settings.value(IniKey_ViewerInherit).toBool()) {
146 pal.setColor(QPalette::Base,
147 settings.value(IniKey_ViewColorBgNormal).value<QColor>());
148 pal.setColor(QPalette::Text,
149 settings.value(IniKey_ViewColorFgNormal).value<QColor>());
152 pal.setColor(QPalette::Base,
153 settings.value(IniKey_ViewerColorBg).value<QColor>());
154 pal.setColor(QPalette::Text,
155 settings.value(IniKey_ViewerColorFg).value<QColor>());
158 setFont(settings.value(IniKey_ViewerFont).value<QFont>());
161 void SimpleTextView::convertFromEUC()
163 QTextCodec *codec = QTextCodec::codecForName("EUC-JP");
164 setPlainText(codec->toUnicode(m_source));
165 getMainWnd()->statusBar()->showMessage("EUC-JP");
168 void SimpleTextView::convertFromJIS()
170 QTextCodec *codec = QTextCodec::codecForName("ISO 2022-JP");
171 setPlainText(codec->toUnicode(m_source));
172 getMainWnd()->statusBar()->showMessage("ISO 2022-JP");
175 void SimpleTextView::convertFromSJIS()
177 QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
178 setPlainText(codec->toUnicode(m_source));
179 getMainWnd()->statusBar()->showMessage("Shift-JIS");
183 void SimpleTextView::convertFromUTF8()
185 QTextCodec *codec = QTextCodec::codecForName("UTF-8");
186 setPlainText(codec->toUnicode(m_source));
187 getMainWnd()->statusBar()->showMessage("UTF-8");
190 void SimpleTextView::convertFromUTF16()
192 QTextCodec *codec = QTextCodec::codecForName("UTF-16");
193 setPlainText(codec->toUnicode(m_source));
194 getMainWnd()->statusBar()->showMessage("UTF-16");
197 void SimpleTextView::convertFromUTF16BE()
199 QTextCodec *codec = QTextCodec::codecForName("UTF-16BE");
200 setPlainText(codec->toUnicode(m_source));
201 getMainWnd()->statusBar()->showMessage("UTF-16BE");
204 void SimpleTextView::convertFromUTF16LE()
206 QTextCodec *codec = QTextCodec::codecForName("UTF-16LE");
207 setPlainText(codec->toUnicode(m_source));
208 getMainWnd()->statusBar()->showMessage("UTF-16LE");
211 void SimpleTextView::onCopyAvailable(bool yes)
213 m_copy->setEnabled(yes);
216 void SimpleTextView::back()
218 emit viewFinished(this);
221 void SimpleTextView::keyPressEvent(QKeyEvent *event)
223 QString ksq = KeyEventToSequence(event);
225 if (ProcessShortcut(ksq, this)) {
230 if (ProcessShortcut(ksq, getMainWnd())) {
235 QPlainTextEdit::keyPressEvent(event);
239 void SimpleTextView::contextMenuEvent(QContextMenuEvent *event)
241 qDebug() << "contextMenuEvent();";
243 menu.addAction(m_convEUC);
244 menu.addAction(m_convJIS);
245 menu.addAction(m_convSJIS);
246 menu.addAction(m_convUTF8);
247 menu.addAction(m_convUTF16BE);
248 menu.addAction(m_convUTF16LE);
250 menu.addAction(m_copy);
252 menu.addAction(m_back);
253 menu.exec(event->globalPos());
256 // http://dobon.net/vb/dotnet/string/detectcode.html より拝借
257 std::string SimpleTextView::detectCode(const QByteArray &bytes)
259 typedef unsigned char byte;
260 const byte bEscape = 0x1B;
261 const byte bAt = 0x40;
262 const byte bDollar = 0x24;
263 const byte bAnd = 0x26;
264 const byte bOpen = 0x28; //'('
265 const byte bB = 0x42;
266 const byte bD = 0x44;
267 const byte bJ = 0x4A;
268 const byte bI = 0x49;
270 int len = bytes.size();
273 bool isBinary = false;
274 for (int i = 0; i < len; i++) {
276 if (b1 <= 0x06 || b1 == 0x7F || b1 == 0xFF) {
279 if (b1 == 0x00 && i < len - 1 && static_cast<byte>(bytes[i + 1]) <= 0x7F) {
288 bool notJapanese = true;
289 for (int i = 0; i < len; i++) {
291 if (b1 == bEscape || 0x80 <= b1) {
300 for (int i = 0; i < len - 2; i++) {
306 if ((b2 == bDollar && b3 == bAt) ||
307 (b2 == bDollar && b3 == bB) ||
308 (b2 == bOpen && (b3 == bB || b3 == bJ)) ||
309 (b2 == bOpen && b3 == bI))
311 return "ISO 2022-JP";
315 if (b2 == bDollar && b3 == bOpen && b4 == bD) {
316 return "ISO 2022-JP";
319 b2 == bAnd && b3 == bAt && b4 == bEscape &&
320 bytes[i + 4] == bDollar && bytes[i + 5] == bB)
322 return "ISO 2022-JP";
331 for (int i = 0; i < len - 1; i++) {
334 if (((0x81 <= b1 && b1 <= 0x9F) || (0xE0 <= b1 && b1 <= 0xFC)) &&
335 ((0x40 <= b2 && b2 <= 0x7E) || (0x80 <= b2 && b2 <= 0xFC)))
341 for (int i = 0; i < len - 1; i++) {
344 if (((0xA1 <= b1 && b1 <= 0xFE) && (0xA1 <= b2 && b2 <= 0xFE)) ||
345 (b1 == 0x8E && (0xA1 <= b2 && b2 <= 0xDF)))
350 else if (i < len - 2) {
352 if (b1 == 0x8F && (0xA1 <= b2 && b2 <= 0xFE) &&
353 (0xA1 <= b3 && b3 <= 0xFE))
360 for (int i = 0; i < len - 1; i++) {
363 if ((0xC0 <= b1 && b1 <= 0xDF) && (0x80 <= b2 && b2 <= 0xBF)) {
367 else if (i < len - 2) {
369 if ((0xE0 <= b1 && b1 <= 0xEF) && (0x80 <= b2 && b2 <= 0xBF) &&
370 (0x80 <= b3 && b3 <= 0xBF))
378 if (euc > sjis && euc > utf8) {
381 else if (sjis > euc && sjis > utf8) {
384 else if (utf8 > euc && utf8 > sjis) {