7 #include <QMutexLocker>
9 #include <QJsonDocument>
10 #include <QJsonObject>
14 // HtmlStringFragments --------------------------------------------------------
16 void TM::HtmlStringFragments::set_range(HtmlRange range)
21 for(HtmlNode const &node : range)
23 if(node.type() != HtmlNode::Text) continue;
24 HtmlStringFragment fragment;
26 fragment.string = node.value();
27 m_fragments.append(fragment);
29 for(HtmlStringFragment &fragment : m_fragments)
32 QString &string = fragment.string;
33 for(QChar const &ch : string)
35 QChar c = trim_whitespace(ch);
36 if(c != '\0') result.append(c);
40 QString &front = m_fragments.front().string;
41 if(front.startsWith(' ')) front.remove(0, 1);
42 QString &tail = m_fragments.back().string;
43 if(tail.endsWith(' ')) tail.remove(tail.size() - 1, 1);
46 QChar TM::HtmlStringFragments::trim_whitespace(QChar const &ch)
75 QString TM::HtmlStringFragments::to_string()
79 for(HtmlStringFragment const &fragment : m_fragments)
81 result.append(fragment.string);
87 // SocketConnection -----------------------------------------------------------
89 TM::SocketConnection::SocketConnection(Widget *widget, QWebSocket *socket)
92 , m_mutex(QMutex::Recursive)
95 connect(socket, SIGNAL(textMessageReceived(QString const&)),
96 this, SLOT(onTextMessageReceived(QString const&)));
97 connect(socket, SIGNAL(binaryMessageReceived(QByteArray const&)),
98 this, SLOT(onBinaryMessageReceived(QByteArray const&)));
101 TM::SocketConnection::~SocketConnection()
103 m_widget->detach(this);
106 QWebSocket* TM::SocketConnection::socket()
108 QWebSocket * result = qobject_cast<QWebSocket*>(parent());
113 void TM::SocketConnection::send_message(QString const &message)
115 socket()->sendTextMessage(message);
118 void TM::SocketConnection::send_message(QJsonObject const &json)
122 send_message(doc.toJson().data());
125 void TM::SocketConnection::changeEditMode(bool edit_mode)
127 set_edit_mode(edit_mode);
130 void TM::SocketConnection::set_edit_mode(bool edit_mode)
132 if(edit_mode == m_edit_mode) return;
134 m_edit_mode = edit_mode;
136 json["cmd"] = "set_edit_mode";
137 json["edit_mode"] = edit_mode;
143 * \brief ウェブブラウザ上でクリックされ、editコマンドが発行されたときに呼び出されます。
145 void TM::SocketConnection::do_edit(QJsonObject const &json)
147 m_document.set_content(json["source"].toString().toUtf8());
148 HtmlNode body = m_document.first("html").first("body");
149 m_fragments.set_range(HtmlRange(body, body));
150 m_widget->set_string(m_fragments.to_string(), json["target"].toString());
151 //emit editCmd(json["id"].toInt(), m_document.to_string());
154 reply["cmd"] = "doedit";
155 reply["id"] = json["id"].toString();
156 reply["html"] = "test2";
158 doc.setObject(reply);
159 send_message(doc.toJson().data());
164 * \brief ウェブブラウザ上でドキュメントがフォーカスを取得し、
165 * focusコマンドが発行されたときに呼び出されます。
167 void TM::SocketConnection::do_focus(QJsonObject const &json)
169 m_widget->attach(this);
170 bool edit_mode = json["edit_mode"].toBool();
171 m_edit_mode = edit_mode;
172 m_widget->set_edit_mode(edit_mode);
175 void TM::SocketConnection::do_blur(QJsonObject const &)
177 //m_widget->detach(this);
180 void TM::SocketConnection::do_load(const QJsonObject &json)
182 m_widget->attach(this);
183 bool edit_mode = json["edit_mode"].toBool();
184 m_edit_mode = edit_mode;
185 m_widget->set_edit_mode(edit_mode);
187 //set_edit_mode(m_widget->edit_mode());
190 void TM::SocketConnection::onTextMessageReceived(QString const &message)
192 QJsonObject json = QJsonDocument::fromJson(message.toUtf8()).object();
193 QString cmd = json["cmd"].toString();
194 if(cmd == "edit") do_edit(json);
195 else if(cmd == "focus") do_focus(json);
196 else if(cmd == "blur") do_blur(json);
197 else if(cmd == "load") do_load(json);
200 void TM::SocketConnection::onBinaryMessageReceived(QByteArray const &message)
207 // SocketServer ---------------------------------------------------------------
209 TM::SocketServer::SocketServer(Widget *widget, quint16 port, QObject *parent)
211 , m_server(new QWebSocketServer(QStringLiteral("wordring websocket"),
212 QWebSocketServer::NonSecureMode, this))
215 bool result = m_server->listen(QHostAddress::LocalHost, port);
216 if(!result) qFatal("An error occured in SocketServer(quint16, QObject*).");
218 connect(m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
221 quint16 TM::SocketServer::port() const
223 return m_server->serverPort();
226 void TM::SocketServer::onNewConnection()
228 QWebSocket *socket = m_server->nextPendingConnection();
229 connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
230 new SocketConnection(m_widget, socket);
233 void TM::SocketServer::onDisconnected()
235 QWebSocket *socket = qobject_cast<QWebSocket*>(sender());
236 socket->deleteLater();