bool HtmlHandler::fatalError(const QXmlParseException & exception)
{
- //m_document->m_error_message = exception.message();
- qDebug() << exception.message();
+ qCritical() << exception.message();
return false;
}
// bool HtmlHandler::ignorableWhitespace(QString const &ch) { return true; }
// bool HtmlHandler::internalEntityDecl(QString const &name, QString const &value) { return true; }
// bool HtmlHandler::processingInstruction(QString const &target, QString const &data) { return true; }
-// bool HtmlHandler::resolveEntity(QString const &publicId, QString const &systemId, QXmlInputSource *& ret) { return true; }
+/*
+bool HtmlHandler::resolveEntity(QString const &publicId, QString const &systemId, QXmlInputSource *& ret)
+{
+ qDebug() << "HtmlHandler::resolveEntity:" << publicId << ", " << systemId;
+ ret = 0;
+ return true;
+}
+*/
// void HtmlHandler::setDocumentLocator(QXmlLocator * locator) { return true; }
-// bool HtmlHandler::skippedEntity(QString const &name) { return true; }
+bool HtmlHandler::skippedEntity(QString const &name)
+{
+ if(name == "nbsp") return characters(" ");
+ return true;
+}
// bool HtmlHandler::startCDATA() { return true; }
-
-// bool HtmlHandler::startEntity(QString const &name) { return true; }
+/*
+bool HtmlHandler::startEntity(QString const &name)
+{
+ qDebug() << "HtmlHandler::startEntity: " << name;
+ return true;
+}
+*/
// bool HtmlHandler::startPrefixMapping(QString const &prefix, QString const &uri) { return true; }
// bool HtmlHandler::warning(const QXmlParseException & exception) { return true; }
// virtual bool attributeDecl(QString const &eName, QString const &aName,
//QString const &type, QString const &valueDefault, QString const &value);
- virtual bool comment(string_type const &ch);
+ bool comment(string_type const &ch);
// virtual bool endCDATA();
// virtual bool endEntity(QString const &name);
// virtual bool endPrefixMapping(QString const &prefix);
// virtual bool ignorableWhitespace(QString const &ch);
// virtual bool internalEntityDecl(QString const &name, QString const &value);
// virtual bool processingInstruction(QString const &target, QString const &data);
-// virtual bool resolveEntity(QString const &publicId, QString const &systemId, QXmlInputSource *&ret);
+// bool resolveEntity(QString const &publicId, QString const &systemId, QXmlInputSource *&ret);
// virtual void setDocumentLocator(QXmlLocator * locator);
-// virtual bool skippedEntity(QString const &name);
+ bool skippedEntity(QString const &name);
// virtual bool startCDATA();
-// virtual bool startEntity(QString const &name);
+// bool startEntity(QString const &name);
// virtual bool startPrefixMapping(QString const &prefix, QString const &uri);
// virtual bool warning(QXmlParseException const &exception);
case 3:
if('A' <= c && c <= 'Z')
{
- Text::pointer s = Text::create(result, cstring);
- s->set_data(RangeData::create(begin_, tail_));
- result->append(s);
+ stuff_sentence(result, cstring, begin_, tail_);
cstring.clear();
goto s0;
}
tail_ = i;
cstring.push_back(c);
}
- if(!cstring.isEmpty())
- {
- Text::pointer s = Text::create(result, cstring);
- s->set_data(RangeData::create(begin_, tail_));
- result->append(s);
- }
+ if(!cstring.isEmpty()) stuff_sentence(result, cstring, begin_, tail_);
return result;
}
return result;
}
+QString EnglishPlugin::normalize(QString string)
+{
+ return string.toLower();
+}
+
+void EnglishPlugin::stuff_sentence(Text::pointer parent, QString string,
+ int begin_, int tail_)
+{
+ // 先頭の空白文字を取り除く。
+ while(string.startsWith(' '))
+ {
+ string.remove(0, 1);
+ ++begin_;
+ }
+ // 後方の空白文字を取り除く。
+ while(string.endsWith(' '))
+ {
+ string.remove(string.size() - 1, 1);
+ --tail_;
+ }
+ if(string.isEmpty()) return; // 空白文字を取り除いた結果、空になった場合、ここで終わる。
+
+ // センテンス追加。
+ Text::pointer s = Text::create(parent, string);
+ s->set_data(RangeData::create(begin_, tail_));
+ parent->append(s);
+}
Text::pointer divide_into_sentences(QString string);
Text::pointer divide_into_words(Text::pointer sentence);
+ QString normalize(QString string);
+
+private:
+ void stuff_sentence(Text::pointer parent, QString string,
+ int begin_, int tail_);
+
private:
Settings const *m_settings;
};
return result;
}
-
+QString JapanesePlugin::normalize(QString string)
+{
+ return string;
+}
Text::pointer divide_into_sentences(QString string);
Text::pointer divide_into_words(Text::pointer sentence);
+ QString normalize(QString string);
+
private:
Settings const *m_settings;
return result;
}
+ /*!
+ * \brief 引数として与えられた文字列を正規化して返します。
+ */
+ virtual QString normalize(QString string) = 0;
};
Q_DECLARE_INTERFACE(Language, "net.wordring.tm.language/1.0")
if(!settings.contains("SocketServer/port")) settings.setValue("SocketServer/port", 8081);
// ProxyModule
if(!settings.contains("ProxyModule/prefix")) settings.setValue("ProxyModule/prefix", "/?");
+ // ProxyHandler
+ if(!settings.contains("ProxyHandler/jscode"))
+ settings.setValue("ProxyHandler/jscode", "C:/Users/Kouichi/Documents/OSDN/wordring-tm/proxy/tm.js");
// Database
if(!settings.contains("Database/root"))
service->load_languages(QApplication::applicationDirPath() + "/plugins");
HttpServer *server = new HttpServer(&settings, &w);
+ w.set_http_port(server->port());
- TM::SocketServer *socket = new TM::SocketServer(&settings, w.editor_widget(), &w);
+ TM::SocketServer *socket = new TM::SocketServer(&settings, service, w.editor_widget(), &w);
server->install(new TM::ProxyModule(
- "/tm?", server->port(), socket->port(), server));
+ &settings, server->port(), socket->port(), server));
QObject::connect(&w, SIGNAL(closing()), socket, SLOT(abort()));
w.show();
TM::EditorWidget* MainWindow::editor_widget() { return m_editor_widget; }
+void MainWindow::set_http_port(quint16 http_port)
+{
+ editor_widget()->set_http_port(http_port);
+}
+
void MainWindow::closeEvent(QCloseEvent *ev)
{
emit closing();
~MainWindow();
TM::EditorWidget* editor_widget();
+ void set_http_port(quint16 http_port);
signals:
void closing();
},
onerror: function(ev) {
- document.location.href = 'http://www.yahoo.co.jp/'; },
+ //document.location.href = 'http://www.yahoo.co.jp/';
+ },
onclose: function(ev) {
//alert('接続が閉じられました');
"CREATE TABLE IF NOT EXISTS sentences("
"sentence_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
"crc INTEGER,"
- "source_id INTEGER,"
- "sentence TEXT,"
+ "UNIQUE(source_id INTEGER, sentence TEXT),"
"json TEXT,"
"user_id INTEGER,"
"time TIMESTAMP);");
q = m_database.exec("CREATE INDEX IF NOT EXISTS crc_index ON sentences(crc);");
if(q.lastError().isValid())
qFatal("An error occured while create index in SentenceDatabase().");
+
q = m_database.exec("CREATE INDEX IF NOT EXISTS source_id_index ON sentences(source_id);");
if(q.lastError().isValid())
qFatal("An error occured while create index in SentenceDatabase().");
+
q = m_database.exec("CREATE INDEX IF NOT EXISTS sentence_index ON sentences(sentence);");
if(q.lastError().isValid())
qFatal("An error occured while create index in SentenceDatabase().");
// クエリ作成。
m_find_sentence_id.reset(new QSqlQuery(m_database));
ret = m_find_sentence_id->prepare("SELECT sentence_id FROM sentences WHERE sentence=?;");
- if(!ret) qFatal("An error occured while prepare select statement in SentenceDatabase().");
+ if(!ret) qFatal("An error occured while prepare find_sentence_id statement in SentenceDatabase().");
+
+ m_find_sentence_by_crc.reset(new QSqlQuery(m_database));
+ ret = m_find_sentence->prepare("SELECT * FROM sentences WHERE crc=?;");
+ if(!ret) qFatal("An error occured while prepare find_sentence_by_crc statement in SentenceDatabase().");
+
+ m_find_sentence_by_source_id.reset(new QSqlQuery(m_database));
+ ret = m_find_sentence->prepare("SELECT * FROM sentences WHERE source_id=?;");
+ if(!ret) qFatal("An error occured while prepare select_by_crc statement in SentenceDatabase().");
m_insert_sentence.reset(new QSqlQuery(m_database));
ret = m_insert_sentence->prepare(
- "INSERT INTO sentences(crc, source_id, sentence, json, user_id, time) "
+ "INSERT OR REPLACE INTO sentences(crc, source_id, sentence, json, user_id, time) "
"VALUES(?, ?, ?, ?, ?, ?);");
if(!ret) qFatal("An error occured while prepare insert statement in SentenceDatabase().");
-
-
}
TM::SentenceDatabase::~SentenceDatabase()
return 0;
}
+/*bool TM::SentenceDatabase::find_sentence(QString sentence,
+ QString *tsentence, QJsonArray *json)
+{
+
+}
+*/
void TM::SentenceDatabase::insert(int source_id, QString sentence, QString json, int user_id)
{
QSqlQuery *q = m_insert_sentence.get();
return p->sentence_id(sentence);
}
+bool TM::Database::find_sentence(int site_id, int scode, QString ssentence, int tcode,
+ QString *tsentence, QJsonArray *json)
+{
+ SentenceDatabase::pointer p = find_sentence_database(site_id, scode);
+ //p->;
+
+ return true;
+}
+
+void TM::Database::insert_sentence(int site_id, int code, int source_id,
+ QString sentence, QString json, int user_id)
+{
+
+}
+
QString TM::Database::root_key() { return "Database/root"; }
~SentenceDatabase();
int sentence_id(QString sentence);
+
+// bool find_sentence_by_source_sentence(
+// QString sentence, QString *tsentence, QJsonArray *json = nullptr);
+ bool find_sentence_by_crc(
+ quint32 crc, QString *tsentence, QJsonArray *json = nullptr);
+ bool find_sentence_by_source_id(
+ int source_id, QString *tsentence, QJsonArray *json = nullptr);
+
void insert(int source_id, QString sentence, QString json, int user_id);
private:
QSqlDatabase m_database;
query_pointer m_find_sentence_id;
+ query_pointer m_find_sentence;
+ query_pointer m_find_sentence_by_crc;
+ query_pointer m_find_sentence_by_source_id;
query_pointer m_insert_sentence;
};
void open_word_database(int code, QString name);
int find_word_id(int code, QString word);
-
+private:
SentenceDatabase::pointer find_sentence_database(int site_id, int code);
+public:
int find_sentence_id(int site_id, int code, QString sentence);
+ bool find_sentence(int site_id, int scode, QString ssentence, int tcode,
+ QString *tsentence, QJsonArray *json);
+ void insert_sentence(int site_id, int code, int source_id,
+ QString sentence, QString json, int user_id);
static QString root_key();
signals:
, m_mutex(QMutex::Recursive)
, m_service(service)
, m_settings(settings)
+ , m_http_port(80)
, m_socket(nullptr)
{
QVBoxLayout *vlayout = new QVBoxLayout(this);
m_socket = nullptr;
}
+void TM::EditorWidget::set_http_port(quint16 http_port) { m_http_port = http_port; }
+
/*!
* \brief 編集モードを変更します。
*/
m_edit_mode->setChecked(mode);
}
+/*!
+ * \brief 編集モードの場合trueを返します。
+ */
bool TM::EditorWidget::edit_mode()
{
QMutexLocker lock(&m_mutex);
return m_edit_mode->isChecked();
}
+/*!
+ * \brief リンクモードを設定します。
+ */
void TM::EditorWidget::set_link_mode(bool mode)
{
QMutexLocker lock(&m_mutex);
m_link->setChecked(mode);
}
+/*!
+ * \brief リンクモードの場合、trueを返します。
+ */
bool TM::EditorWidget::link_mode()
{
QMutexLocker lock(&m_mutex);
m_link->setDisabled(disable);
}
+/*!
+ * \brief 原文の言語コードを返します。
+ */
int TM::EditorWidget::source_language()
{
QMutexLocker lock(&m_mutex);
return m_slang->data().toInt();
}
+/*!
+ * \brief 訳文の言語コードを返します。
+ */
int TM::EditorWidget::target_language()
{
QMutexLocker lock(&m_mutex);
m_edit->set_sentences(result);
}
+/*!
+ * \brief 言語プラグインが読み込まれるたびに呼び出されます。
+ * \param code 言語コード。
+ * \param name 言語名。
+ * \param icon 言語を表すアイコン。
+ */
void TM::EditorWidget::onLanguageLoaded(int code, QString name, QIcon icon)
{
QString dslanguage = m_settings->value("Widget/defaultSourceLanguage", "English").toString();
connect(taction, SIGNAL(triggered(bool)), this, SLOT(onTargetLanguageTriggered(bool)));
}
+/*!
+ * \brief 編集アイコンがクリックされたとき呼び出されます。
+ */
void TM::EditorWidget::onEditModeTriggered(bool)
{
QAction *edit_mode = qobject_cast<QAction*>(sender());
m_edit->set_edit_mode(checked);
}
+/*!
+ * \brief リンクアイコンがクリックされたとき呼び出されます。
+ */
void TM::EditorWidget::onLinkModeTriggered(bool checked)
{
//QAction *link_mode = qobject_cast<QAction*>(sender());
m_edit->set_link_mode(checked);
}
+/*!
+ * \brief アクションから原文言語が変更されたとき呼び出されます。
+ */
void TM::EditorWidget::onSourceLanguageTriggered(bool)
{
QAction *saction = qobject_cast<QAction*>(sender());
m_slang->setData(saction->data());
}
+/*!
+ * \brief アクションから訳文言語が変更されたとき呼び出されます。
+ */
void TM::EditorWidget::onTargetLanguageTriggered(bool)
{
QAction *taction = qobject_cast<QAction*>(sender());
assert(taction);
m_tlang->setIcon(taction->icon());
m_tlang->setData(taction->data());
-
}
+/*!
+ * \brief ブラウザ・アイコンがクリックされたとき呼び出されます。
+ */
void TM::EditorWidget::onBrowserTriggered(bool)
{
- QDesktopServices::openUrl(QUrl("http://localhost/"));
+ QString url("http://localhost:");
+ url += QString::number(m_http_port) + "/";
+
+ QDesktopServices::openUrl(QUrl(url));
}
// EditorPanel ----------------------------------------------------------------
{
}
+/*!
+ * \brief 親となるエディタを設定します。
+ */
void TM::EditorPanel::set_editor(Editor *editor)
{
assert(!m_editor);
m_editor = editor;
}
+/*!
+ * \brief 保持している文を返します。
+ */
Text::pointer TM::EditorPanel::sentence() { return m_sentence; }
+/*!
+ * \brief 文を設定します。
+ */
void TM::EditorPanel::set_sentence(Text::pointer sentence)
{
assert(sentence);
}
}
-bool TM::EditorPanel::is_empty() const
-{
- qDebug() << document()->isEmpty();
- return document()->isEmpty();
- if(!m_sentence) return true;
- for(Text::const_pointer p = m_sentence->begin(); p; p = p->next())
- if(!p->string().isEmpty()) return true;
- return false;
-}
+/*!
+ * \brief 内容が空の場合、trueを返します。
+ */
+bool TM::EditorPanel::is_empty() const { return document()->isEmpty(); }
+/*!
+ * \brief 引数として与えられた単語に該当する範囲を選択するカーソルを返します。
+ */
QTextCursor TM::EditorPanel::select_cursor(Text::pointer word)
{
RangeData *rd = static_cast<RangeData*>(word->data().get());
return c;
}
+/*!
+ * \brief 引数として与えられた位置にある単語を返します。
+ */
Text::pointer TM::EditorPanel::select_word(QPoint const &pos)
{
QTextCursor c = cursorForPosition(pos);
return &m_linker;
}
+/*!
+ * \brief 保持するリンクを色分け表示します。
+ */
void TM::SourcePanel::ensure_highlight()
{
clear_highlight();
: EditorPanel(parent)
, m_source_panel(nullptr)
, m_text_dirty(false)
+ , m_text_saved(true)
{
//setContextMenuPolicy(Qt::NoContextMenu);
}
{
EditorPanel::set_sentence(sentence);
set_text_dirty(false);
+ set_text_saved(false);
+}
+
+/*!
+ * \brief データベースへの登録が必要な場合、falseを返します。
+ *
+ * パネル内の文字列が編集された場合、trueを返します。
+ * 原文パネルがフォーカスを失うと、エディタがこのメンバを呼び出し、
+ * データベース登録の必要性を判定します。
+ * その後、エディタはデータベース登録を行い、フラグをクリアするので、
+ * 次に文字列が編集されるまでtrueを返し続けます。
+ */
+bool TM::TargetPanel::is_text_saved() const { return m_text_saved; }
+
+void TM::TargetPanel::set_text_saved(bool saved)
+{
+ m_text_saved = saved;
}
+/*!
+ * \brief パネル内の文字列が編集された場合、trueを返します。
+ *
+ * エディタがリンクモードに入るとき、このメンバを呼び出し、
+ * 単語へ分割する必要があるか判定します。
+ * エディタはパネルの文字列を単語に分割した後、set_sentence()によって
+ * パネルに文を設定するため、次に文字列を編集するまでfalseを返すようになります。
+ */
bool TM::TargetPanel::is_text_dirty() const { return m_text_dirty; }
+/*!
+ * \brief パネルの文字列が編集されたかを示すフラグを設定します。
+ */
void TM::TargetPanel::set_text_dirty(bool dirty)
{
m_text_dirty = dirty;
- if(dirty) m_editor->parent_widget()->set_link_mode_disabled(false);
+ if(dirty) m_editor->parent_editor_widget()->set_link_mode_disabled(false);
}
bool TM::TargetPanel::canInsertFromMimeData(QMimeData const *source) const
{
TextPanel::insertFromMimeData(source);
set_text_dirty(true);
+ set_text_saved(false);
}
void TM::TargetPanel::inputMethodEvent(QInputMethodEvent *ev)
{
if(m_editor->link_mode()) ev->setCommitString("");
- if(!ev->commitString().isEmpty()) set_text_dirty(true);
+ if(!ev->commitString().isEmpty())
+ {
+ set_text_dirty(true);
+ set_text_saved(false);
+ }
QPlainTextEdit::inputMethodEvent(ev);
}
else
{
TextPanel::keyPressEvent(ev);
- if(!ev->text().isEmpty()) set_text_dirty(true);
+ if(!ev->text().isEmpty())
+ {
+ set_text_dirty(true);
+ set_text_saved(false);
+ }
}
}
ta->clear();
// リンクモードの解除。
set_link_mode(false);
- parent_widget()->set_link_mode_disabled(true);
+ parent_editor_widget()->set_link_mode_disabled(true);
}
/*!
assert(!mode_ || can_link_mode()); // リンクモードに入るには、条件がある。
m_link_mode = mode_;
- parent_widget()->set_link_mode(mode_);
+ parent_editor_widget()->set_link_mode(mode_);
if(mode_) do_link_mode_enter(m_current_source_panel);
else if(m_current_source_panel) do_link_mode_leave(m_current_source_panel);
return true;
}
-TM::EditorWidget* TM::Editor::parent_widget()
+TM::EditorWidget* TM::Editor::parent_editor_widget()
{
EditorWidget* result = qobject_cast<EditorWidget*>(parentWidget());
assert(result);
TargetPanel *tp = panel->target_panel();
assert(tp);
tp->show();
- if(can_link_mode()) parent_widget()->set_link_mode_disabled(false);
+ if(can_link_mode()) parent_editor_widget()->set_link_mode_disabled(false);
}
/*!
tp->hide();
set_link_mode(false);
- parent_widget()->set_link_mode_disabled(true);
+ parent_editor_widget()->set_link_mode_disabled(true);
- qDebug() << "focus out";
+ if(!tp->is_text_saved())
+ {
+ //qDebug() << m_service->si
+ tp->set_text_saved(true);
+ }
}
/*!
assert(panel);
TargetPanel *tp = panel->target_panel();
assert(tp);
- int tcode = parent_widget()->target_language();
+ int tcode = parent_editor_widget()->target_language();
if(tp->is_text_dirty())
{
if(sentences->size())
{
Text::pointer words = m_service->divide_into_words(tcode, sentences->begin());
- tp->set_sentence(words);
+ tp->set_sentence(words); // ココで、text_dirtyがfalseになる。
}
}
qDebug() << m_current_source_panel->linker()->to_json_array();
assert(panel);
panel->commit_link();
- panel->clear_highlight();
+ //panel->clear_highlight();
}
void attach(SocketConnection *socket);
void detach(SocketConnection *socket);
+ void set_http_port(quint16 http_port);
+
void set_edit_mode(bool mode);
bool edit_mode();
void set_link_mode(bool mode);
int target_language();
void set_string(QString source_, QString target_);
+ void append_sentence();
+ void save_sentence();
signals:
void editModeChanged(bool mode_);
void linkModeChanged(bool mode_);
+ void contentsEdited();
+
public slots:
void onLanguageLoaded(int code, QString name, QIcon icon);
void onEditModeTriggered(bool);
QMutex m_mutex;
Service *m_service;
Settings *m_settings;
+ quint16 m_http_port;
SocketConnection *m_socket;
QToolBar *m_toolbar;
void set_sentence(Text::pointer sentence);
+ bool is_text_saved() const;
+ void set_text_saved(bool saved);
+
bool is_text_dirty() const;
void set_text_dirty(bool dirty);
private:
SourcePanel *m_source_panel;
- bool m_text_dirty;
+ bool m_text_dirty; /*!< 内容の変更を示すフラグ */
+ bool m_text_saved; /*!< データベース登録の必要性を示すフラグ */
};
class Editor : public TextWidget
{
Q_OBJECT
-/* enum : int
- {
- TextSourceSentence = QTextCharFormat::UserProperty,
- TextSourceWord,
- TextTargetSentence = QTextCharFormat::UserProperty + 10,
- TextTargetWord,
- TextCurrentBlock,
- TextCurrentEditor,
- };
-*/
public:
Editor(Settings *settings, Service *service, QWidget *parent);
bool can_link_mode() const;
- EditorWidget* parent_widget();
+ EditorWidget* parent_editor_widget();
TargetPanel* current_target_panel();
TargetPanel const* current_target_panel() const;
#include "html.h"
#include "htmlprivate.h"
#include "tmservice.h"
+#include "settings.h"
#include <QThread>
// ProxyContext ---------------------------------------------------------------
-TM::ProxyContext::ProxyContext(QString prefix, quint16 http, quint16 socket)
+TM::ProxyContext::ProxyContext(Settings *settings, quint16 http, quint16 socket)
: QObject(0)
+ , m_settings(settings)
, m_manager(new QNetworkAccessManager(this))
, m_cookie(new QNetworkCookieJar(this))
- , m_prefix(prefix)
- , m_http(http)
- , m_socket(socket)
+ , m_http_port(http)
+ , 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();
}
+QNetworkAccessManager* TM::ProxyContext::network_access_manager()
+{
+ return m_manager;
+}
+
+quint16 TM::ProxyContext::http_port() const { return m_http_port; }
+
+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; }
+
// ProxyModule ----------------------------------------------------------------
-TM::ProxyModule::ProxyModule(QString prefix, quint16 http, quint16 socket, QObject *parent)
+TM::ProxyModule::ProxyModule(Settings *settings, quint16 http, quint16 socket,
+ QObject *parent)
: HttpModule(parent)
, m_thread(new QThread(this))
- , m_context(new ProxyContext(prefix, http, socket))
- , m_prefix(prefix)
- , m_http(http)
+ , m_context(new ProxyContext(settings, http, socket))
{
m_context->moveToThread(m_thread);
connect(m_thread, SIGNAL(finished()), m_context, SLOT(deleteLater()));
HttpHandler* TM::ProxyModule::create_handler(QByteArray method, QByteArray url)
{
if(method.toLower() != "get") return nullptr;
- if(!url.toLower().startsWith(m_prefix.toUtf8())) return nullptr;
+ if(!url.toLower().startsWith(m_context->prefix().toUtf8())) return nullptr;
HttpHandler *handler = new ProxyHandler(m_context);
handler->moveToThread(m_thread);
int TM::ProxyHandler::run()
{
m_targetUrl = QUrl::fromUserInput(
- m_request->url().remove(0, m_context->m_prefix.toUtf8().length()));
+ m_request->url().remove(0, m_context->prefix().toUtf8().length()));
// HTML取得要求
- m_reply = m_context->m_manager->get(QNetworkRequest(m_targetUrl));
+ m_reply = m_context->network_access_manager()->get(QNetworkRequest(m_targetUrl));
connect(m_reply, SIGNAL(finished()), this, SLOT(onNetworkReplyFinished()));
return 0;
}
node = head.insert("style", head.end());
node.insert_text(" .wordring-segment:hover{ color:#ff0000; } ", node.end());
// JS書き込み
- //QFile file("C:\\Users\\Kouichi\\Documents\\GitHub\\TM\\Proxy\\tm.js");
- QFile file("tm.js");
+ QFile file(m_context->jscode());
file.open(QIODevice::ReadOnly);
QByteArray js = file.readAll();
file.close();
//
node = head.insert("script", head.end()).set_attribute("type", "text/javascript");
QString str1 = "\nwindow.wordring.port=";
- str1 += QString::number(m_context->m_socket) + ";\n";
+ str1 += QString::number(m_context->socket_port()) + ";\n";
node.insert_comment(str1, node.end());
// パラグラフ設定
create_paragraph(body.lbegin(), body.ltail());
*/
QString TM::ProxyHandler::host() const
{
- return QString("http://localhost:") + QString::number(m_context->m_http);
+ return QString("http://localhost:") + QString::number(m_context->http_port());
}
/*!
*
* 例)/tm?
*/
-QString TM::ProxyHandler::prefix() const
-{
- return m_context->m_prefix;
-}
+QString TM::ProxyHandler::prefix() const { return m_context->prefix(); }
#include <QObject>
#include <QThread>
+#include <QMutex>
#include <QUrl>
QT_BEGIN_NAMESPACE
class ProxyContext : public QObject
{
Q_OBJECT
- friend class ProxyHandler;
public:
- ProxyContext(QString prefix, quint16 http, quint16 socket);
+ ProxyContext(Settings *settings, quint16 http, quint16 socket);
+
+ QNetworkAccessManager* network_access_manager();
+ quint16 http_port() const;
+ quint16 socket_port() const;
+ QString prefix() const;
+ QString jscode() const;
private:
+ Settings *m_settings;
+
QNetworkAccessManager *m_manager;
QNetworkCookieJar *m_cookie;
+ quint16 m_http_port;
+ quint16 m_socket_port;
QString m_prefix;
- quint16 m_http;
- quint16 m_socket;
+ QString m_jscode;
};
class ProxyModule : public HttpModule
Q_OBJECT
public:
- ProxyModule(QString prefix, quint16 http, quint16 socket, QObject *parent);
+ ProxyModule(Settings *settings, quint16 http, quint16 socket, QObject *parent);
~ProxyModule();
virtual HttpHandler* create_handler(QByteArray method, QByteArray url);
private:
QThread *m_thread;
ProxyContext *m_context;
-
- QString m_prefix;
- quint16 m_http;
};
class ProxyHandler : public HttpHandler
#include "tmdatabase.h"
#include <QDir>
+
#include <QMutex>
#include <QMutexLocker>
return m_languages[code]->divide_into_words(sentence);
}
+/*!
+ * \brief 原文と訳文の対をデータベースへ登録します。
+ * \param site_id 翻訳対象サイトを表すID。
+ * \param scode 原文の言語コード。
+ * \param ssentence 原文の構造化テキスト。
+ * \param tcode 訳文の言語コード。
+ * \param tsentence 訳文の構造化テキスト。
+ * \param json 原文と訳文間の単語リンク。
+ */
+void TM::Service::insert_sentence(int site_id, int scode, Text::pointer ssentence,
+ int tcode, Text::pointer tsentence, QJsonArray json)
+{
+ QMutexLocker lock(&m_mutex);
+
+ assert(m_languages.contains(scode));
+ assert(m_languages.contains(tcode));
+ Language *slanguage = m_languages[scode];
+ Language *tlanguage = m_languages[tcode];
+
+ QString sstring = slanguage->normalize(ssentence->to_string());
+ QString tstring = tlanguage->normalize(tsentence->to_string());
+
+ //m_database->
+}
+
+/*!
+ * \brief 原文から訳文を検索します。
+ * \param site_id 翻訳対象サイトを表すID。
+ * \param scode 原文の言語コード。
+ * \param ssentence 原文の構造化テキスト。
+ * \param tcode 訳文の言語コード。
+ * \param tsentence 訳文の構造化テキストを受け取るポインタ。
+ * \param json 原文と訳文間の単語リンクを受け取るポインタ。
+ * \return 訳文が検索できた場合、trueを返します。
+ */
+bool TM::Service::find_sentence(int site_id, int scode, Text::pointer ssentence, int tcode,
+ Text::pointer *tsentence, QJsonArray *json)
+{
+ return true;
+}
#include "language.h"
#include <QObject>
-#include <QByteArray>
#include <QString>
+#include <QByteArray>
+#include <QJsonArray>
#include <QMap>
#include <QIcon>
Text::pointer divide_into_sentences(int code, QString string);
Text::pointer divide_into_words(int code, Text::pointer sentence);
- //int find_source_id(int code, QString const &source);
+ void insert_sentence(int site_id, int scode, Text::pointer ssentence,
+ int tcode, Text::pointer tsentence, QJsonArray json);
+ bool find_sentence(int site_id, int scode, Text::pointer ssentence, int tcode,
+ Text::pointer *tsentence, QJsonArray *json);
signals:
/*!
// SocketConnection -----------------------------------------------------------
-TM::SocketConnection::SocketConnection(EditorWidget *editor_widget, QWebSocket *socket)
+TM::SocketConnection::SocketConnection(Settings *settings, Service *service,
+ EditorWidget *editor_widget, QWebSocket *socket)
: QObject(socket)
+ , m_settings(settings)
+ , m_service(service)
, m_editor_widget(editor_widget)
, m_mutex(QMutex::Recursive)
, m_edit_mode(false)
// SocketServer ---------------------------------------------------------------
-TM::SocketServer::SocketServer(Settings *settings, EditorWidget *editor_widget, QObject *parent)
+TM::SocketServer::SocketServer(Settings *settings, Service* service,
+ EditorWidget *editor_widget, QObject *parent)
: QObject(parent)
, m_settings(settings)
+ , m_service(service)
, m_server(new QWebSocketServer(QStringLiteral("wordring websocket"),
QWebSocketServer::NonSecureMode, this))
, m_editor_widget(editor_widget)
{
QWebSocket *socket = m_server->nextPendingConnection();
connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
- new SocketConnection(m_editor_widget, socket);
+ new SocketConnection(m_settings, m_service, m_editor_widget, socket);
m_sockets.push_back(socket);
}
#include <QString>
#include <QList>
+#include <QJsonArray>
+#include <QThread>
#include <QMutex>
#include <QWebSocket>
namespace TM
{
+class Service;
class EditorWidget;
class HtmlData : public RangeData
HtmlNode m_node;
};
+/*!
+ * \brief HtmlRangeから構造化テキストに変換するためのクラスです。
+ */
class TextConverter
{
public:
- //TextConverter();
-
Text::pointer to_text(HtmlRange range);
Text::pointer stuff_text(Text::pointer parent, QString const &string);
int m_state;
};
+class TextSentence
+{
+
+private:
+ Text::pointer m_source_sentence;
+ Text::pointer m_target_sentence;
+ QJsonArray m_link_data;
+};
+
+class TextSegment
+{
+
+};
+
class SocketConnection : public QObject
{
Q_OBJECT
public:
- SocketConnection(EditorWidget *editor_widget, QWebSocket *socket);
+ SocketConnection(Settings *settings, Service *service,
+ EditorWidget *editor_widget, QWebSocket *socket);
virtual ~SocketConnection();
//quint16 port() const;
void onBinaryMessageReceived(QByteArray const &message);
private:
+ Settings *m_settings;
+ Service *m_service;
+
QMutex m_mutex;
bool m_edit_mode;
{
Q_OBJECT
public:
- SocketServer(Settings *settings, EditorWidget *editor_widget, QObject *parent);
+ SocketServer(Settings *settings, Service* service,
+ EditorWidget *editor_widget, QObject *parent);
~SocketServer();
quint16 port() const;
private:
Settings *m_settings;
+ Service *m_service;
+
QWebSocketServer *m_server;
- EditorWidget *m_editor_widget;
QList<QWebSocket*> m_sockets;
+
+ EditorWidget *m_editor_widget;
};
} // namespace TM
return insert_after(position_, create(self(), string_));
}
+Text::pointer Text::remove(pointer position_)
+{
+ assert(false); // 未実装
+ return position_;
+}
+
QString& Text::string() { return m_string; }
+
QString const& Text::string() const { return m_string; }
Text& Text::set_string(QString const &string)
pointer append(pointer value_);
pointer append(QString const &string_);
+
pointer insert(pointer position_, pointer value_);
pointer insert(pointer position_, QString const &string_);
pointer insert_after(pointer position, pointer value);
pointer insert_after(pointer position_, QString const &string_);
+ pointer remove(pointer position_);
+
QString& string();
QString const& string() const;
Text& set_string(QString const &string);