--- /dev/null
+#include "tmtext.h"
+
+#include "debug.h"
+
+// WordLink -------------------------------------------------------------------
+
+TM::WordLink::WordLink() { }
+
+TM::WordLink::WordLink(int place, Text::pointer word)
+{
+ append(place, word);
+}
+
+void TM::WordLink::clear()
+{
+ m_sources.clear();
+ m_targets.clear();
+}
+
+void TM::WordLink::append(int place, Text::pointer word)
+{
+ assert(word);
+ if(place == Source)
+ {
+ if(!m_sources.contains(word)) m_sources.push_back(word);
+ }
+ if(place == Target)
+ {
+ if(!m_targets.contains(word)) m_targets.push_back(word);
+ }
+}
+
+void TM::WordLink::remove(int place, Text::pointer word)
+{
+ assert(word);
+ if(place == Source) m_sources.removeOne(word);
+ if(place == Target) m_targets.removeAll(word);
+}
+
+bool TM::WordLink::is_valid() const
+{
+ return (!m_sources.isEmpty()) && (!m_targets.isEmpty());
+}
+
+bool TM::WordLink::is_empty() const
+{
+ if(!m_sources.isEmpty()) return false;
+ if(!m_targets.isEmpty()) return false;
+ return true;
+}
+
+bool TM::WordLink::contains(int place, Text::pointer word)
+{
+ if(place == Source) return m_sources.contains(word);
+ if(place == Target) return m_targets.contains(word);
+ return false;
+}
+
+int TM::WordLink::size(int place) const
+{
+ if(place == Source) return m_sources.size();
+ if(place == Target) return m_targets.size();
+ return -1;
+}
+
+TM::WordLink::storage_type* TM::WordLink::sources() { return &m_sources; }
+
+TM::WordLink::storage_type* TM::WordLink::targets() { return &m_targets; }
+
+QString TM::WordLink::debug_dump() const
+{
+ QString result;
+ for(Text::pointer p : m_sources) result += p->string() + ",";
+ result += ":";
+ for(Text::pointer p : m_targets) result += p->string() + ",";
+ return result;
+}
+
+TM::WordLink::pointer TM::WordLink::create() { return pointer(new WordLink()); }
+
+TM::WordLink::pointer TM::WordLink::create(int place, Text::pointer word)
+{
+ return pointer(new WordLink(place, word));
+}
+
+// WordLinker -----------------------------------------------------------------
+
+/*!
+ * \brief リンクの編集を開始します。
+ */
+void TM::WordLinker::start()
+{
+ if(!m_current_link) m_current_link = WordLink::create();
+}
+
+/*!
+ * \brief リンクの編集を終了します。
+ */
+void TM::WordLinker::commit()
+{
+ if(!m_current_link) return;
+ if(m_current_link->is_valid()) m_links.append(m_current_link);
+ m_current_link.reset();
+}
+
+/*!
+ * \brief 現在のリンクへ単語を追加します。
+ */
+void TM::WordLinker::append(int place, Text::pointer word)
+{
+ assert(word);
+ if(!m_current_link) start();
+
+ WordLink::pointer p = find(place, word);
+ if(m_current_link->is_empty() && p)
+ {
+ m_current_link = p;
+ m_links.removeOne(p);
+ }
+ else
+ {
+ if(p)
+ {
+ p->remove(place, word);
+ if(p->size(place) == 0) m_links.removeOne(p);
+ }
+ m_current_link->append(place, word);
+ }
+}
+
+/*!
+ * \brief 現在のリンクから単語を削除します。
+ */
+void TM::WordLinker::remove(int place, Text::pointer word)
+{
+ assert(word);
+ assert(m_current_link);
+ m_current_link->remove(place, word);
+}
+
+/*!
+ * \brief 現在のリンクから単語の選択状態を反転させます。
+ */
+void TM::WordLinker::toggle(int place, Text::pointer word)
+{
+ assert(word);
+
+ bool contains = false;
+ if(m_current_link) contains = m_current_link->contains(place, word);
+ if(contains) remove(place, word);
+ else append(place, word);
+}
+
+/*!
+ * \brief 現在選択されているリンクを返します。
+ */
+TM::WordLink::pointer TM::WordLinker::current() { return m_current_link; }
+
+/*!
+ * \brief valueを含むWordLinkを検索します。
+ */
+TM::WordLink::pointer TM::WordLinker::find(Text::pointer word)
+{
+ WordLink::pointer p;
+ if(p = find(WordLink::Source, word)) return p;
+ if(p = find(WordLink::Target, word)) return p;
+ return p;
+}
+
+/*!
+ * \brief placeからvalueを含むWordLinkを検索します。
+ */
+TM::WordLink::pointer TM::WordLinker::find(int place, Text::pointer word)
+{
+ for(WordLink::pointer p : m_links) if(p->contains(place, word)) return p;
+ return WordLink::pointer();
+}
+
+int TM::WordLinker::index_of(WordLink::pointer link) const
+{
+ if(m_current_link == link) return 0;
+ int i = m_links.indexOf(link);
+ assert(0 <= i);
+ return (i < 0) ? -1 : i + 1;
+}
+
+TM::WordLinker::iterator TM::WordLinker::begin() { return m_links.begin(); }
+
+TM::WordLinker::iterator TM::WordLinker::end() { return m_links.end(); }
+
+QString TM::WordLinker::debug_dump() const
+{
+ QString result;
+ for(WordLink::pointer p : m_links) result += p->debug_dump() + "|";
+ return result;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#include "tmwidget.h"
#include "tmservice.h"
#include "tmsocket.h"
+#include "tmtext.h"
#include <QSettings>
#include <QToolBar>
#include <QBrush>
#include <QFont>
+#include <QMimeData>
+
+#include <QList>
#include <memory>
#include "debug.h"
-TM::Widget::Widget(Service *service, QSettings *settings, QWidget *parent)
+TM::Widget::Widget(QSettings *settings, Service *service, QWidget *parent)
: QWidget(parent)
, m_mutex(QMutex::Recursive)
, m_service(service)
QAction *setting = new QAction(QIcon(":/setting.png"), "setting", this);
m_toolbar->addAction(setting);
- m_edit = new Editor(this);
+ m_edit = new Editor(settings, service, this);
vlayout->addWidget(m_toolbar);
vlayout->addWidget(m_edit);
QMutexLocker lock(&m_mutex);
m_socket = socket;
connect(this, SIGNAL(editModeChanged(bool)), m_socket, SLOT(changeEditMode(bool)));
+ m_link->setDisabled(true);
}
void TM::Widget::detach(SocketConnection *)
m_socket = nullptr;
}
+/*!
+ * \brief 編集モードを変更します。
+ */
void TM::Widget::set_edit_mode(bool mode)
{
QMutexLocker lock(&m_mutex);
+ bool old_mode = m_edit_mode->isChecked();
+ if(old_mode == mode) return;
+
m_edit_mode->setChecked(mode);
}
return m_edit_mode->isChecked();
}
+void TM::Widget::set_link_mode(bool mode)
+{
+ QMutexLocker lock(&m_mutex);
+ bool old_mode = m_link->isChecked();
+ if(old_mode == mode) return;
+
+ m_link->setChecked(mode);
+}
+
+bool TM::Widget::link_mode()
+{
+ QMutexLocker lock(&m_mutex);
+ return m_link->isChecked();
+}
+
+void TM::Widget::disable_link_mode(bool disable)
+{
+ QMutexLocker lock(&m_mutex);
+ m_link->setDisabled(disable);
+}
+
+int TM::Widget::source_language()
+{
+ QMutexLocker lock(&m_mutex);
+ return m_slang->data().toInt();
+}
+
+int TM::Widget::target_language()
+{
+ QMutexLocker lock(&m_mutex);
+ return m_tlang->data().toInt();
+}
+
void TM::Widget::set_string(QString source_, QString target_)
{
QMutexLocker lock(&m_mutex);
{
QAction *edit_mode = qobject_cast<QAction*>(sender());
bool checked = edit_mode->isChecked();
- m_link->setDisabled(!checked);
+ m_link->setDisabled(true);
m_slang->setDisabled(!checked);
m_tlang->setDisabled(!checked);
emit editModeChanged(checked);
+
m_edit->set_edit_mode(checked);
}
{
//QAction *link_mode = qobject_cast<QAction*>(sender());
m_edit->set_link_mode(checked);
- if(!checked) return;
- if(TargetPanel *tp = m_edit->current_target_panel())
- {
- int code = m_tlang->data().toInt();
- QString string = tp->toPlainText();
- Text::pointer sentences = m_service->divide_into_sentences(code, string);
- if(sentences->size())
- {
- Text::pointer words = m_service->divide_into_words(code, sentences->begin());
- tp->set_sentence(words);
- }
- }
}
void TM::Widget::onSourceLanguageTriggered(bool)
QDesktopServices::openUrl(QUrl("http://localhost/"));
}
+// EditorPanel ----------------------------------------------------------------
+
+TM::EditorPanel::EditorPanel(QWidget *parent)
+ : TextPanel(parent)
+ , m_editor(nullptr)
+{
+}
+
+void TM::EditorPanel::set_editor(Editor *editor)
+{
+ assert(!m_editor);
+ m_editor = editor;
+}
+
+Text::pointer TM::EditorPanel::sentence() { return m_sentence; }
+
+void TM::EditorPanel::set_sentence(Text::pointer sentence)
+{
+ assert(sentence);
+ m_sentence = sentence;
+ clear();
+ QTextCursor c = textCursor();
+ for(Text::pointer p = sentence->begin(); p; p = p->next()) // p=word
+ {
+ QTextCharFormat cf;
+ QVariant v = QVariant::fromValue(Text::weak_pointer(p));
+ cf.setProperty(Word, v);
+ c.insertText(p->string(), cf);
+ }
+}
+
+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;
+}
+
+QTextCursor TM::EditorPanel::select_cursor(Text::pointer word)
+{
+ RangeData *rd = static_cast<RangeData*>(word->data().get());
+ assert(rd);
+ int slength = word->string().length();
+ QTextCursor c = textCursor();
+ c.movePosition(QTextCursor::Start);
+ c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, rd->begin());
+ c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, slength);
+ return c;
+}
+
+Text::pointer TM::EditorPanel::select_word(QPoint const &pos)
+{
+ QTextCursor c = cursorForPosition(pos);
+ // Textを取得する。
+ QVariant v = c.charFormat().property(Word);
+ if(!v.isValid()) return Text::pointer();
+ Text::weak_pointer wp = v.value<Text::weak_pointer>();
+ assert(!wp.expired());
+ Text::pointer p = wp.lock();
+ return p;
+}
+
+/*!
+ * \brief wordの範囲に背景色colorを設定します。
+ *
+ * 透過色は、Qt::transparentです。
+ */
+void TM::EditorPanel::highlight(Text::pointer word, QColor color)
+{
+ QTextCursor c = select_cursor(word);
+ QTextCharFormat cf = c.charFormat();
+ cf.setBackground(color);
+ c.mergeCharFormat(cf);
+}
+
+void TM::EditorPanel::highlight(WordLink::storage_type *link, QColor color)
+{
+ for(Text::pointer p : *link) highlight(p, color);
+}
+
+void TM::EditorPanel::clear_highlight()
+{
+ if(m_sentence) set_sentence(m_sentence);
+}
+
+/*!
+ * \brief 引数として与えられた整数値から色を作成します。
+ *
+ * 色分け用に使えるQColorを返します。
+ */
+QColor TM::EditorPanel::color(int index) const
+{
+ QColor result;
+ result.setHsv(index * 199, 128, 128, 128);
+ return result;
+}
+
// SourcePanel ----------------------------------------------------------------
TM::SourcePanel::SourcePanel(QWidget *parent)
- : TextPanel(parent)
+ : EditorPanel(parent)
, m_target_panel(nullptr)
{
setUndoRedoEnabled(false);
m_target_panel = target;
}
-void TM::SourcePanel::set_sentence(Text::pointer sentence)
+void TM::SourcePanel::commit_link()
{
- m_sentence = sentence;
- clear();
- QTextCursor c = textCursor();
- for(Text::pointer p = sentence->begin(); p; p = p->next())
+ m_linker.commit();
+ clear_highlight();
+ m_target_panel->clear_highlight();
+}
+
+TM::WordLinker* TM::SourcePanel::linker()
+{
+ return &m_linker;
+}
+
+void TM::SourcePanel::ensure_highlight()
+{
+ clear_highlight();
+ m_target_panel->clear_highlight();
+
+ WordLink::pointer wl = m_linker.current();
+ if(wl)
{
- QTextCharFormat cf;
- QVariant v = QVariant::fromValue(Text::weak_pointer(p));
- cf.setProperty(SourceWord, v);
- c.insertText(p->string(), cf);
+ highlight(wl->sources(), Qt::cyan);
+ target_panel()->highlight(wl->targets(), Qt::cyan);
+ }
+
+ for(WordLink::pointer wl : m_linker)
+ {
+ int index = m_linker.index_of(wl);
+ QColor c = color(index);
+ highlight(wl->sources(), c);
+ target_panel()->highlight(wl->targets(), c);
}
}
+
bool TM::SourcePanel::canInsertFromMimeData(const QMimeData *) const
{
- return false; // ドロップ禁止
+ return false; // ドロップ禁止カーソルにする
}
-void TM::SourcePanel::insertFromMimeData(const QMimeData *) { }
+void TM::SourcePanel::insertFromMimeData(const QMimeData *) { } // ドロップされても何もしない
void TM::SourcePanel::inputMethodEvent(QInputMethodEvent *ev)
{
- ev->setCommitString("");
+ ev->setCommitString(""); // 入力禁止
QPlainTextEdit::inputMethodEvent(ev);
}
int key = ev->key();
switch(key)
{
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ if(m_editor->link_mode()) m_editor->set_link_mode(false);
+ break;
case Qt::Key_C:
if(!ev->modifiers().testFlag(Qt::ControlModifier)) break;
case Qt::Key_Left:
void TM::SourcePanel::do_click(QPoint const &pos)
{
- QTextCursor c = cursorForPosition(pos);
- QTextCharFormat cf = c.charFormat();
- QVariant v = c.charFormat().property(SourceWord);
- assert(v.isValid());
- Text::weak_pointer wp = v.value<Text::weak_pointer>();
- assert(!wp.expired());
- Text::pointer p = wp.lock();
- RangeData *rd = static_cast<RangeData*>(p->data().get());
- assert(rd);
- c.movePosition(QTextCursor::Start);
- c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, rd->begin());
- qDebug() << wp.lock()->string() << rd->begin() << ":" << rd->tail();
- int slength = p->string().length();
- c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, slength);
- qDebug() << "format size: " << document()->allFormats().size();
- cf.setBackground(Qt::cyan);
- c.mergeCharFormat(cf);
- //setTextCursor(c);
+ if(m_editor->link_mode()) do_click_in_link_mode(pos);
+}
+
+void TM::SourcePanel::do_click_in_link_mode(QPoint const &pos)
+{
+ Text::pointer w = select_word(pos);
+ if(!w) return;
+
+ m_linker.toggle(WordLink::Source, w);
+ ensure_highlight();
+ setTextCursor(cursorForPosition(pos));
}
void TM::SourcePanel::do_focusin()
void TM::SourcePanel::do_focusout()
{
- //if(m_target_panel) m_target_panel->hide();
}
// TargetPanel ----------------------------------------------------------------
TM::TargetPanel::TargetPanel(QWidget *parent)
- : TextPanel(parent)
+ : EditorPanel(parent)
, m_source_panel(nullptr)
+ , m_text_dirty(false)
{
//setContextMenuPolicy(Qt::NoContextMenu);
}
+TM::SourcePanel* TM::TargetPanel::source_panel() { return m_source_panel; }
+
void TM::TargetPanel::set_source_panel(SourcePanel *source)
{
m_source_panel = source;
}
-Text::pointer TM::TargetPanel::sentence() { return m_sentence; }
-
void TM::TargetPanel::set_sentence(Text::pointer sentence)
{
- assert(sentence);
- m_sentence = sentence;
- clear();
- QTextCursor c = textCursor();
- for(Text::pointer p = sentence->begin(); p; p = p->next())
- {
- RangeData *rd = static_cast<RangeData*>(p->data().get()); QTextCursor c = textCursor();
- qDebug() << rd->begin() << "," << rd->tail() << ": " << p->string();
+ EditorPanel::set_sentence(sentence);
+ set_text_dirty(false);
+}
- QTextCharFormat cf;
- QVariant v = QVariant::fromValue(Text::weak_pointer(p));
- cf.setProperty(TargetWord, v);
- c.insertText(p->string(), cf);
- }
+bool TM::TargetPanel::is_text_dirty() const { return m_text_dirty; }
+
+void TM::TargetPanel::set_text_dirty(bool dirty) { m_text_dirty = dirty; }
+
+bool TM::TargetPanel::canInsertFromMimeData(QMimeData const *source) const
+{
+ if(source->hasText()) return true;
+ return false;
+}
+
+void TM::TargetPanel::inputMethodEvent(QInputMethodEvent *ev)
+{
+ if(m_editor->link_mode()) ev->setCommitString("");
+ if(!ev->commitString().isEmpty()) set_text_dirty(true);
+ QPlainTextEdit::inputMethodEvent(ev);
+}
+
+void TM::TargetPanel::keyPressEvent_(QKeyEvent *ev)
+{
+ if(m_editor->link_mode()) do_key_press_in_link_mode(ev);
+ else QPlainTextEdit::keyPressEvent(ev);
+}
+
+void TM::TargetPanel::do_click(QPoint const &pos)
+{
+ if(m_editor->link_mode()) do_click_in_link_mode(pos);
+}
+
+void TM::TargetPanel::do_click_in_link_mode(QPoint const &pos)
+{
+ Text::pointer w = select_word(pos);
+ if(!w) return;
+
+ WordLinker *wl = m_source_panel->linker();
+ wl->toggle(WordLink::Target, w);
+ m_source_panel->ensure_highlight();
+ setTextCursor(cursorForPosition(pos));
}
void TM::TargetPanel::do_focusin()
//hide();
}
+void TM::TargetPanel::do_key_press_in_link_mode(QKeyEvent *ev)
+{
+ int key = ev->key();
+ switch(key)
+ {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ if(m_editor->link_mode()) m_editor->set_link_mode(false);
+ break;
+ }
+
+}
+
// Editor ---------------------------------------------------------------------
-TM::Editor::Editor(QWidget *parent)
+TM::Editor::Editor(QSettings *settings, Service *service, QWidget *parent)
: TextWidget(parent)
+ , m_settings(settings)
+ , m_service(service)
, m_edit_mode(false)
, m_link_mode(false)
, m_current_source_panel(nullptr)
{
TextArea *ta = text_area();
connect(ta, SIGNAL(focusInChild(TextPanel*,TextPanel*)), this, SLOT(onFocusInChild(TextPanel*,TextPanel*)));
+}
- /*QObject::connect(ta, &TextArea::focusChanged, [=](TextPanel *new_, TextPanel *old_){
- if(m_current_editor_panel) m_current_editor_panel->hide();
- TmpData* td = new_->user_data<TmpData>();
- if(td) current_editor_panel = td->data;
- //assert(current_editor_panel);
- if(current_editor_panel) current_editor_panel->show();
- });*/
+void TM::Editor::clear()
+{
+ m_sentences.reset();
+ m_current_source_panel = nullptr;
+ TextArea *ta = text_area();
+ ta->clear();
+ set_link_mode(false);
}
void TM::Editor::set_sentences(Text::pointer sentences)
{
+ clear();
m_sentences = sentences;
TextArea *ta = text_area();
- ta->clear();
-
for(Text::pointer s = sentences->begin(); s; s = s->next()) // s: sentence
{
SourcePanel *sp = ta->append<SourcePanel>();
TargetPanel *tp = ta->append<TargetPanel>();
sp->set_target_panel(tp);
+ sp->set_editor(this);
tp->set_source_panel(sp);
+ tp->set_editor(this);
sp->set_sentence(s);
sp->show();
}
}
+bool TM::Editor::edit_mode() const { return m_edit_mode; }
+
void TM::Editor::set_edit_mode(bool mode_) { m_edit_mode = mode_; }
+bool TM::Editor::link_mode() const { return m_link_mode; }
+
void TM::Editor::set_link_mode(bool mode_)
{
+ if(mode_ == m_link_mode) return; // モードが変化していない場合、何もしない。
+ assert(!mode_ || can_link_mode()); // リンクモードに入るには、条件がある。
+
m_link_mode = mode_;
+ parent_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);
+}
+
+bool TM::Editor::can_link_mode() const
+{
+ if(!m_current_source_panel) return false;
+ if(!edit_mode()) return false;
+ if(current_target_panel()->is_empty()) return false;
+
+ return true;
+}
+
+TM::Widget* TM::Editor::parent_widget()
+{
+ Widget* result = qobject_cast<Widget*>(parentWidget());
+ assert(result);
+ return result;
}
TM::TargetPanel* TM::Editor::current_target_panel()
return result;
}
-void TM::Editor::onFocusInChild(TextPanel *new_, TextPanel *)
+TM::TargetPanel const* TM::Editor::current_target_panel() const
+{
+ return const_cast<Editor*>(this)->current_target_panel();
+}
+/*
+bool TM::Editor::is_panel_changed(TextPanel *new_) const
{
- for(TextPanel *p : *text_area())
- {
- TargetPanel *tp = qobject_cast<TargetPanel*>(p);
- if(tp) tp->hide();
- }
SourcePanel *sp = qobject_cast<SourcePanel*>(new_);
- if(sp)
- {
- sp->target_panel()->show();
- m_current_source_panel = sp;
- }
+ if(sp) return sp != m_current_source_panel;
TargetPanel *tp = qobject_cast<TargetPanel*>(new_);
- if(tp) tp->show();
+ if(tp) return tp->source_panel() != m_current_source_panel;
+ assert(false);
+ return false;
+}
+*/
+void TM::Editor::onFocusInChild(TextPanel *new_, TextPanel *)
+{
+ SourcePanel *old_panel = m_current_source_panel;
+ SourcePanel *new_panel = find_source_panel(new_);
+ assert(new_panel);
+
+ if(old_panel && old_panel != new_panel) do_panel_leave(old_panel);
+ m_current_source_panel = new_panel;
+ if(old_panel != new_panel) do_panel_enter(new_panel);
+}
+
+TM::SourcePanel* TM::Editor::find_source_panel(TextPanel *panel)
+{
+ SourcePanel *sp = qobject_cast<SourcePanel*>(panel);
+ if(sp) return sp;
+ TargetPanel *tp = qobject_cast<TargetPanel*>(panel);
+ if(tp) return tp->source_panel();
+ return nullptr;
+}
+
+/*!
+ * \brief 文を表示するパネルにフォーカスが入るとき呼び出されます。
+ */
+void TM::Editor::do_panel_enter(SourcePanel *panel)
+{
+ TargetPanel *tp = panel->target_panel();
+ assert(tp);
+ tp->show();
+ if(can_link_mode()) parent_widget()->disable_link_mode(false);
+}
+
+/*!
+ * \brief 文を表示するパネルからフォーカスが出るとき呼び出されます。
+ */
+void TM::Editor::do_panel_leave(SourcePanel *panel)
+{
+ TargetPanel *tp = panel->target_panel();
+ assert(tp);
+ tp->hide();
+
+ set_link_mode(false);
+ parent_widget()->disable_link_mode(true);
}
+void TM::Editor::do_link_mode_enter(SourcePanel *panel)
+{
+ assert(panel);
+ TargetPanel *tp = panel->target_panel();
+ assert(tp);
+ int tcode = parent_widget()->target_language();
+ if(tp && tp->is_text_dirty())
+ {
+ qDebug() << "dirty";
+ QString string = tp->toPlainText();
+ Text::pointer sentences = m_service->divide_into_sentences(tcode, string);
+ if(sentences->size())
+ {
+ Text::pointer words = m_service->divide_into_words(tcode, sentences->begin());
+ tp->set_sentence(words);
+ }
+ }
+
+ panel->ensure_highlight();
+}
+void TM::Editor::do_link_mode_leave(SourcePanel *panel)
+{
+ assert(panel);
+ panel->commit_link();
+ panel->clear_highlight();
+ qDebug() << "do_link_mode_leave";
+}
#ifndef TMWIDGET_H
#define TMWIDGET_H
+#include "tmtext.h"
#include "textwidget.h"
#include "html.h"
#include "language.h"
#include <QList>
#include <QIcon>
#include <QString>
+#include <QColor>
#include <QMutex>
{
Q_OBJECT
public:
- explicit Widget(Service *service, QSettings *settings, QWidget *parent = 0);
+ Widget(QSettings *settings, Service *service, QWidget *parent = 0);
void attach(SocketConnection *socket);
void detach(SocketConnection *socket);
void set_edit_mode(bool mode);
bool edit_mode();
+ void set_link_mode(bool mode);
+ bool link_mode();
+ void disable_link_mode(bool disable);
+
+ int source_language();
+ int target_language();
void set_string(QString source_, QString target_);
Editor *m_edit;
};
-class SourcePanel : public TextPanel
+class EditorPanel : public TextPanel
{
Q_OBJECT
public:
- enum : int
- {
- SourceWord = QTextCharFormat::UserProperty,
- };
+ enum : int { Word = QTextFormat::UserProperty };
+
+public:
+ explicit EditorPanel(QWidget *parent);
+ void set_editor(Editor *editor);
+
+ Text::pointer sentence();
+ virtual void set_sentence(Text::pointer sentence);
+
+ bool is_empty() const;
+
+ QTextCursor select_cursor(Text::pointer word);
+ Text::pointer select_word(QPoint const &pos);
+ void highlight(Text::pointer word, QColor color);
+ void highlight(WordLink::storage_type *link, QColor color);
+ void clear_highlight();
+
+ QColor color(int index) const;
+
+protected:
+ Editor *m_editor;
+ Text::pointer m_sentence;
+};
+class SourcePanel : public EditorPanel
+{
+ Q_OBJECT
public:
- SourcePanel(QWidget *parent);
+ explicit SourcePanel(QWidget *parent);
- Editor* editor();
TargetPanel* target_panel();
void set_target_panel(TargetPanel *target);
- void set_sentence(Text::pointer sentence);
+
+ void commit_link();
+ WordLinker* linker();
+
+ void ensure_highlight();
protected:
- bool canInsertFromMimeData(const QMimeData * source) const;
- void insertFromMimeData(const QMimeData * source);
+ bool canInsertFromMimeData(QMimeData const *source) const;
+ void insertFromMimeData(QMimeData const *source);
void inputMethodEvent(QInputMethodEvent *ev);
void keyPressEvent(QKeyEvent *ev);
+ //void do_enter();
void do_click(QPoint const &pos);
+ void do_click_in_link_mode(QPoint const &pos);
+
void do_focusin();
void do_focusout();
private:
TargetPanel *m_target_panel;
- Text::pointer m_sentence;
+ WordLinker m_linker;
};
-class TargetPanel: public TextPanel
+class TargetPanel: public EditorPanel
{
Q_OBJECT
public:
- enum : int
- {
- TargetWord = QTextCharFormat::UserProperty,
- };
-
-public:
- TargetPanel(QWidget *parent);
+ explicit TargetPanel(QWidget *parent);
- Editor* editor();
+ SourcePanel* source_panel();
void set_source_panel(SourcePanel *source);
- Text::pointer sentence();
+
void set_sentence(Text::pointer sentence);
+ bool is_text_dirty() const;
+ void set_text_dirty(bool dirty);
+
protected:
+ bool canInsertFromMimeData(QMimeData const *source) const;
+
+ void inputMethodEvent(QInputMethodEvent *ev);
+ void keyPressEvent_(QKeyEvent *ev);
+
+ //void do_enter();
+ void do_click(QPoint const &pos);
+ void do_click_in_link_mode(QPoint const &pos);
+
void do_focusin();
void do_focusout();
+ void do_key_press_in_link_mode(QKeyEvent *ev);
+
private:
SourcePanel *m_source_panel;
- Text::pointer m_sentence;
+ bool m_text_dirty;
};
class Editor : public TextWidget
{
Q_OBJECT
- enum : int
+/* enum : int
{
TextSourceSentence = QTextCharFormat::UserProperty,
TextSourceWord,
TextCurrentBlock,
TextCurrentEditor,
};
+*/
public:
- Editor(QWidget *parent);
+ Editor(QSettings *settings, Service *service, QWidget *parent);
+ void clear();
void set_sentences(Text::pointer sentences);
+
+ bool edit_mode() const;
void set_edit_mode(bool mode_);
+ bool link_mode() const;
void set_link_mode(bool mode_);
+ bool can_link_mode() const;
+
+ Widget* parent_widget();
TargetPanel* current_target_panel();
+ TargetPanel const* current_target_panel() const;
+
+ //bool is_panel_changed(TextPanel *new_) const;
protected slots:
void onFocusInChild(TextPanel *new_, TextPanel *old_);
+protected:
+ SourcePanel* find_source_panel(TextPanel *panel);
+
+ void do_panel_enter(SourcePanel *panel);
+ void do_panel_leave(SourcePanel *panel);
+ void do_link_mode_enter(SourcePanel *panel);
+ void do_link_mode_leave(SourcePanel *panel);
+
private:
+ QSettings *m_settings;
+ Service *m_service;
+
Text::pointer m_sentences;
bool m_edit_mode; /*!< 編集モードのときtrue */
bool m_link_mode; /*!< リンクモードのときtrue */