From 01ce100d2fb24af549771ec159533e553479ac0e Mon Sep 17 00:00:00 2001 From: wordring Date: Fri, 28 Aug 2015 03:15:10 +0900 Subject: [PATCH] =?utf8?q?URL=E5=85=A5=E5=8A=9B=E6=AC=84=E3=81=8B=E3=82=89?= =?utf8?q?=E7=A7=BB=E5=8B=95=E3=81=A7=E3=81=8D=E3=81=AA=E3=81=8F=E3=81=AA?= =?utf8?q?=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F=E5=95=8F=E9=A1=8C=E3=82=92?= =?utf8?q?=E4=BF=AE=E6=AD=A3=E2=99=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- proxy/main.cpp | 29 ++------ proxy/proxy.pro | 2 +- proxy/tm-default.css | 6 ++ proxy/tm-default.js | 145 ++++++++++++++++++++++++++++++++++++ proxy/tmeditorwidget.cpp | 8 ++ proxy/tmeditorwidget.h | 4 +- proxy/tmhttp.cpp | 56 ++++++++------ proxy/tmhttp.h | 6 +- proxy/tmsocket.cpp | 7 ++ proxy/tmsocket.h | 3 +- third-party/katahiromz/wordring.ico | Bin 0 -> 80531 bytes third-party/katahiromz/wordring.png | Bin 0 -> 5716 bytes third-party/katahiromz/wordring.svg | 104 ++++++++++++++++++++++++++ 13 files changed, 318 insertions(+), 52 deletions(-) create mode 100644 proxy/tm-default.css create mode 100644 proxy/tm-default.js create mode 100644 third-party/katahiromz/wordring.ico create mode 100644 third-party/katahiromz/wordring.png create mode 100644 third-party/katahiromz/wordring.svg diff --git a/proxy/main.cpp b/proxy/main.cpp index 40eadf6..052a657 100644 --- a/proxy/main.cpp +++ b/proxy/main.cpp @@ -23,30 +23,10 @@ #include #include "debug.h" -/* -QFile s_debug_file; -void debug_message(QtMsgType, QMessageLogContext const&, QString const &message) -{ - s_debug_file.write(message.toLocal8Bit().data()); - s_debug_file.write("\r\n"); - //fprintf(stdout, "%s\n", message.toLocal8Bit().data()); -} -*/ int main(int argc, char *argv[]) { //SetDebugMemoryLeaks(); -/* - AllocConsole(); - FILE* fp; - freopen_s(&fp, "CON","w",stdout); - freopen_s(&fp, "CON","r",stdin); -*/ -/* s_debug_file.setFileName("wordring_log.txt"); - s_debug_file.open(QIODevice::ReadWrite); - - qInstallMessageHandler(debug_message); -*/ QApplication a(argc, argv); @@ -80,10 +60,13 @@ int main(int argc, char *argv[]) settings.setValue("ProxyModule/prefix", "/?u="); // ProxyHandler #ifdef QT_DEBUG - settings.setValue("ProxyHandler/jscode", QString(PROXYSRCDIR) + "/tm.js"); + settings.setValue("ProxyHandler/js_file", QString(PROXYSRCDIR) + "/tm-default.js"); + settings.setValue("ProxyHandler/css_file", QString(PROXYSRCDIR) + "/tm-default.css"); #else -// if(!settings.contains("ProxyHandler/jscode")) - settings.setValue("ProxyHandler/jscode", app_path + "/tm.js"); +// if(!settings.contains("ProxyHandler/js_file")) + settings.setValue("ProxyHandler/js_file", app_path + "/tm-default.js"); +// if(!settings.contains("ProxyHandler/css_file")) + settings.setValue("ProxyHandler/css_file", app_path + "/tm-default.css"); #endif // DefaultHtmlModule #ifdef QT_DEBUG diff --git a/proxy/proxy.pro b/proxy/proxy.pro index f8230ec..f091117 100644 --- a/proxy/proxy.pro +++ b/proxy/proxy.pro @@ -38,7 +38,7 @@ DEFINES += PROXYSRCDIR=\\\"$$PWD\\\" RESOURCES += \ proxy.qrc -RC_FILE = wordring.rc +#RC_FILE = wordring.rc RC_ICONS = wordring.ico #DISTFILES += diff --git a/proxy/tm-default.css b/proxy/tm-default.css new file mode 100644 index 0000000..c99e0e9 --- /dev/null +++ b/proxy/tm-default.css @@ -0,0 +1,6 @@ + + +body { + font-family: 'ヒラギノ角ゴ ProN W3', 'Hiragino Kaku Gothic ProN', 'メイリオ', Meiryo, sans-serif; +} + diff --git a/proxy/tm-default.js b/proxy/tm-default.js new file mode 100644 index 0000000..7996a1b --- /dev/null +++ b/proxy/tm-default.js @@ -0,0 +1,145 @@ + +window.wordring = { + socket: null, // TMとの通信用ソケット。 + port: 1, // ソケットのポート番号。 + url: '', + edit_mode: false, // 編集モード判別フラグ。 + + segments: null, // パラグラフの連想配列。 + + // ページのセットアップを行う。 + setup: function() { + if(!window.WebSocket) alert('Your browser does not support websocket.\r\nBecause wordring-tm needs it, you must use the latest browser.'); + // 原文のコピーを取る。 + wordring.segments = Array(); + var elements = document.getElementsByTagName('span'); + var element; + var i = 0; + for(; i < elements.length ; i++) + { + element = elements.item(i); + if(!element.hasAttribute('data-wordring-segment')) continue; + + var id = element.getAttribute('data-wordring-segment'); + var segment = {}; + segment.segment_id = id; + segment.loaded = false; + segment.element = element; + segment.html = element.innerHTML; + wordring.segments[id] = segment; + } + + wordring.socket = new WebSocket('ws://localhost:' + window.wordring.port + '/'); + wordring.socket.onopen = wordring.onopen; + wordring.socket.onmessage = wordring.onmessage; + wordring.socket.onerror = wordring.onerror; + wordring.socket.onclose = wordring.onclose; + }, + + onopen: function(ev) { + document.addEventListener('click', wordring.onclick); + window.addEventListener('focus', wordring.onfocus); + window.addEventListener('blur', wordring.onblur); + + wordring.socket.send(JSON.stringify({ + 'cmd': 'load', + 'url': window.wordring.url + })); + + // 全てのセグメントの対して、セグメントの情報を送信する。 + var length = wordring.segments.length; + var i = 0; + for(; i < length; i++) { + var segment = wordring.segments[i]; + wordring.socket.send(JSON.stringify({ + 'cmd': 'load_segment', + 'segment_id': segment.segment_id, + 'html': segment.html + })); + } + }, + + onmessage: function(ev) { + var json = JSON.parse(ev.data); + switch(json.cmd) + { + case 'set_segment': wordring.set_segment(json); break; + case 'set_edit_mode': wordring.set_edit_mode(json); break; + case 'segment_loaded': wordring.segment_loaded(json); break; + case 'reload': wordring.reload(); break; + } + }, + + onerror: function(ev) { + //document.location.href = 'http://www.yahoo.co.jp/'; + }, + + onclose: function(ev) { + window.location.href = 'http://wordring.net/'; + }, + + onfocus: function(ev) { + wordring.socket.send(JSON.stringify({ + 'cmd': 'focus' + })); + }, + + onblur: function(e) { + wordring.socket.send(JSON.stringify({ + 'cmd': 'blur' + })); + + }, + + onclick: function(ev) { + if(!wordring.edit_mode) return; + ev.preventDefault(); + var node; + for(node = ev.target; node.nodeType == Node.ELEMENT_NODE; node = node.parentNode) { + if(node.hasAttribute('data-wordring-segment')) + { + var id = node.getAttribute('data-wordring-segment'); + var segment = wordring.segments[id]; + if(segment.loaded) break; + wordring.socket.send(JSON.stringify({ + 'cmd': 'edit_segment', + 'segment_id': segment.segment_id + })); + break; + } + } + }, + + set_segment: function(json) { + var segment_id = json.segment_id; + wordring.segments[segment_id].element.innerHTML = json.html; + }, + + set_edit_mode: function(json) { + wordring.edit_mode = json.edit_mode; + }, + + segment_loaded: function(json) { + var segment_id = json.segment_id; + var segment = wordring.segments[segment_id]; + segment.loaded = true; + segment.element.className = ''; + }, + + reload: function() { + window.location.reload(); + } +}; + +if(document.addEventListener) +{ + window.addEventListener('load', function(ev){ + wordring.setup(); + }); +} else { + window.attachEvent('onload', function(ev){ + wordring.setup(); + }); +} + + diff --git a/proxy/tmeditorwidget.cpp b/proxy/tmeditorwidget.cpp index b06d9d5..4ae065c 100644 --- a/proxy/tmeditorwidget.cpp +++ b/proxy/tmeditorwidget.cpp @@ -94,6 +94,8 @@ void TM::EditorWidget::attach(SocketConnection *socket) m_socket = socket; connect(this, SIGNAL(editModeChanged(bool)), m_socket, SLOT(changeEditMode(bool))); set_link_mode_disabled(true); + connect(this, SIGNAL(sourceLanguageChanged()), m_socket, SLOT(changeLanguage())); + connect(this, SIGNAL(targetLanguageChanged()), m_socket, SLOT(changeLanguage())); } /*! @@ -104,6 +106,8 @@ void TM::EditorWidget::detach(SocketConnection *) { QMutexLocker lock(&m_mutex); disconnect(this, SIGNAL(editModeChanged(bool)), m_socket, SLOT(changeEditMode(bool))); + disconnect(this, SIGNAL(sourceLanguageChanged()), m_socket, SLOT(changeLanguage())); + disconnect(this, SIGNAL(targetLanguageChanged()), m_socket, SLOT(changeLanguage())); m_edit->clear(); m_socket = nullptr; @@ -273,6 +277,8 @@ void TM::EditorWidget::onSourceLanguageTriggered(bool) assert(saction); m_slang->setIcon(saction->icon()); m_slang->setData(saction->data()); + + emit sourceLanguageChanged(); } /*! @@ -284,6 +290,8 @@ void TM::EditorWidget::onTargetLanguageTriggered(bool) assert(taction); m_tlang->setIcon(taction->icon()); m_tlang->setData(taction->data()); + + emit targetLanguageChanged(); } /*! diff --git a/proxy/tmeditorwidget.h b/proxy/tmeditorwidget.h index f485050..e4a3efe 100644 --- a/proxy/tmeditorwidget.h +++ b/proxy/tmeditorwidget.h @@ -72,8 +72,8 @@ public: signals: void editModeChanged(bool mode_); void linkModeChanged(bool mode_); - - void contentsEdited(); + void sourceLanguageChanged(); + void targetLanguageChanged(); public slots: void onLanguageLoaded(int code, QString name, QIcon icon); diff --git a/proxy/tmhttp.cpp b/proxy/tmhttp.cpp index 4074626..85d720f 100644 --- a/proxy/tmhttp.cpp +++ b/proxy/tmhttp.cpp @@ -26,10 +26,15 @@ TM::ProxyContext::ProxyContext(Settings *settings, quint16 http, quint16 socket) , m_socket_port(socket) { m_manager->setCookieJar(m_cookie); + assert(settings->contains("ProxyModule/prefix")); m_prefix = settings->value("ProxyModule/prefix").toString(); - assert(settings->contains("ProxyHandler/jscode")); - m_jscode = settings->value("ProxyHandler/jscode").toString(); + + assert(settings->contains("ProxyHandler/js_file")); + m_js_file = settings->value("ProxyHandler/js_file").toString(); + + assert(settings->contains("ProxyHandler/css_file")); + m_css_file = settings->value("ProxyHandler/css_file").toString(); } QNetworkAccessManager* TM::ProxyContext::network_access_manager() @@ -43,7 +48,9 @@ quint16 TM::ProxyContext::socket_port() const { return m_socket_port; } QString TM::ProxyContext::prefix() const { return m_prefix; } -QString TM::ProxyContext::jscode() const { return m_jscode; } +QString TM::ProxyContext::js_file() const { return m_js_file; } + +QString TM::ProxyContext::css_file() const { return m_css_file; } // ProxyModule ---------------------------------------------------------------- @@ -96,8 +103,12 @@ TM::ProxyHandler::~ProxyHandler() int TM::ProxyHandler::run() { - m_targetUrl = QUrl::fromUserInput( - m_request->url().remove(0, m_context->prefix().toUtf8().length())); + QByteArray url_string = + m_request->url().remove(0, m_context->prefix().toUtf8().length()); + url_string = QUrl::fromPercentEncoding(url_string).toUtf8(); + m_targetUrl = QUrl::fromUserInput(url_string); + qDebug() << m_targetUrl; + // HTML取得要求 m_reply = m_context->network_access_manager()->get(QNetworkRequest(m_targetUrl)); connect(m_reply, SIGNAL(finished()), this, SLOT(onNetworkReplyFinished())); @@ -175,15 +186,27 @@ int TM::ProxyHandler::response() // CSS書き込み node = head.insert("style", head.end()); node.insert_text(" .wordring-segment:hover{ color:#ff0000; } ", node.end()); - // JS書き込み - QFile file(m_context->jscode()); - file.open(QIODevice::ReadOnly); - QByteArray js = file.readAll(); - file.close(); + // JS書き込み + QFile js_file(m_context->js_file()); + js_file.open(QIODevice::ReadOnly); + assert(js_file.isOpen()); + QByteArray js = js_file.readAll(); + js_file.close(); node = head.insert("script", head.end()).set_attribute("type", "text/javascript"); node.insert_comment(QString::fromUtf8(js), node.end()); - // + + // css書き込み + QFile css_file(m_context->css_file()); + css_file.open(QIODevice::ReadOnly); + assert(css_file.isOpen()); + QByteArray css = css_file.readAll(); + css_file.close(); + node = head.insert("style", head.end()).set_attribute("type", "text/css"); + node.insert_text(QString::fromUtf8(css), node.end()); + + + // ポート、URL書き込み node = head.insert("script", head.end()).set_attribute("type", "text/javascript"); QString str1 = "\nwindow.wordring.port="; str1 += QString::number(m_context->socket_port()) + ";\n"; @@ -400,7 +423,6 @@ TM::DefaultHtmlHandler::DefaultHtmlHandler( , m_html(html_) { QString path = settings->value("DefaultHtmlModule/file").toString(); - QString prefix = settings->value("ProxyModule/prefix").toString(); QFile file(path); file.open(QIODevice::ReadOnly); @@ -412,20 +434,10 @@ TM::DefaultHtmlHandler::DefaultHtmlHandler( HtmlNode html = document.first("html"); HtmlNode head = html.first("head"); - HtmlNode node; // Tidyが書き込むmetaタグを除去 head.remove(head.first("meta")); -/* - node = head.insert("script", head.end()).set_attribute("type", "text/javascript"); - QString js = "\nwindow.wordring.port="; - js += QString::number(port) + ";\n"; - js += "window.wordring.prefix='"; - js += prefix + "';\n"; - node.insert_comment(js, node.end()); -*/ - m_html = document.to_byte_array(); } diff --git a/proxy/tmhttp.h b/proxy/tmhttp.h index 2352e6d..a755634 100644 --- a/proxy/tmhttp.h +++ b/proxy/tmhttp.h @@ -35,7 +35,8 @@ public: quint16 http_port() const; quint16 socket_port() const; QString prefix() const; - QString jscode() const; + QString js_file() const; + QString css_file() const; private: Settings *m_settings; @@ -46,7 +47,8 @@ private: quint16 m_http_port; quint16 m_socket_port; QString m_prefix; - QString m_jscode; + QString m_js_file; + QString m_css_file; }; class ProxyModule : public HttpModule diff --git a/proxy/tmsocket.cpp b/proxy/tmsocket.cpp index 290f153..2143ea7 100644 --- a/proxy/tmsocket.cpp +++ b/proxy/tmsocket.cpp @@ -503,6 +503,13 @@ void TM::SocketConnection::changeEditMode(bool edit_mode) set_edit_mode(edit_mode); } +void TM::SocketConnection::changeLanguage() +{ + QJsonObject json; + json["cmd"] = "reload"; + send_message(json); +} + /*! * \brief ブラウザに編集モードを反映します。 * diff --git a/proxy/tmsocket.h b/proxy/tmsocket.h index e833535..a190340 100644 --- a/proxy/tmsocket.h +++ b/proxy/tmsocket.h @@ -142,8 +142,6 @@ public: void save_sentence(int segment_id, int index); void remove_sentence(int segment_id, int index); - void do_sentence_loaded(); - void sentence_found( int segment_id, int index, sentence_data_type::pointer result); void sentence_inserted(int segment_id, int index, @@ -154,6 +152,7 @@ signals: public slots: void changeEditMode(bool edit_mode); + void changeLanguage(); private: void set_segment(int segment_id, QString html); diff --git a/third-party/katahiromz/wordring.ico b/third-party/katahiromz/wordring.ico new file mode 100644 index 0000000000000000000000000000000000000000..9e61aefd8ac70fb9cc8a4dc6e6c6544dd9eb61d6 GIT binary patch literal 80531 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 Q!THq)$ literal 0 HcmV?d00001 diff --git a/third-party/katahiromz/wordring.svg b/third-party/katahiromz/wordring.svg new file mode 100644 index 0000000..1a44c52 --- /dev/null +++ b/third-party/katahiromz/wordring.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + -- 2.11.0