Replaced all std::cout with kDebug.
[tagua/yd.git] / src / movelist_textual.cpp
blobb485769b0fe833c61c88c501f76fdea96c7e6056
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #ifdef HAVE_KHTML
13 #include <boost/shared_ptr.hpp>
14 #include <iostream>
15 #include <QFile>
16 #include <QHBoxLayout>
17 #include <QTextStream>
18 #include <kurl.h>
19 #include <dom/html_document.h>
20 #include <dom/html_element.h>
21 #include <dom/dom_element.h>
22 #include <dom/dom_text.h>
23 #include <kstandarddirs.h>
24 #include "mastersettings.h"
25 #include "decoratedmove.h"
26 #include "movelist_p.h"
27 #include "movelist_textual.h"
29 namespace MoveList {
31 Textual::Textual(QWidget *parent)
32 : KHTMLPart(parent, parent, KHTMLPart::BrowserViewGUI)
33 , m_curr_selected(-1)
34 , m_layout_style(0) {
36 m_loader.setSize(12);
38 connect(browserExtension(), SIGNAL(openUrlRequest(const KUrl&,const KParts::URLArgs&)),
39 this, SLOT(onURL(const KUrl&)));
40 setJScriptEnabled(false);
41 setJavaEnabled(false);
42 setMetaRefreshEnabled(false);
43 setPluginsEnabled(false);
45 QString fpath = KStandardDirs::locate("appdata", "scripts/movelist_textual.html");
46 //kDebug() << "HTML file is:"<< fpath;
47 QFile file(fpath);
48 file.open(QIODevice::ReadOnly);
49 QTextStream stream(&file);
50 QString html = stream.readAll();
51 //kDebug() << "Using HTML:"<<html;
53 begin();
54 write(html);
55 end();
56 setMove(0, -1, "Mainline:");
59 static void clear_node(DOM::Node n) {
60 if(!n.isNull())
61 while(1) {
62 DOM::Node f = n.firstChild();
63 if(f.isNull())
64 break;
65 n.removeChild(f);
69 static void clear_from(DOM::Node n) {
70 DOM::Node p = n.parentNode();
71 while(1) {
72 DOM::Node next = n.nextSibling();
73 p.removeChild(n);
74 if(next.isNull())
75 break;
76 n = next;
80 void Textual::onURL(const KUrl &url) {
81 QString u = url.url();
82 if(!u.startsWith("index://")) {
83 kDebug() << " --> Error in Textual::onURL, what should i do with url \""<< u <<"\"?";
84 return;
86 QString p = u.mid(8);
87 Index ix = Index::fromString(p);
88 kDebug() << "Open Link \"" << p << "\" = \"" << ix << "\"";
89 m_notifier->onUserSelectMove(ix);
92 void Textual::setComment(const Index& index, const QString& comment) {
93 DOM::HTMLDocument document = htmlDocument();
94 DOM::Element this_cm = document.getElementById("cm_"+index);
95 if(this_cm.isNull()) {
96 kDebug() << " --> Error in Textual::setComment, invalid index!";
97 return;
100 clear_node(this_cm);
101 if(!comment.isEmpty()) {
102 this_cm.appendChild(document.createTextNode(comment));
103 this_cm.appendChild(document.createTextNode(QString(" ")));
107 void Textual::setVComment(const Index& index, int v, const QString& comment) {
108 DOM::HTMLDocument document = htmlDocument();
109 DOM::Element this_cm = document.getElementById("vk_"+index.next(v));
110 if(this_cm.isNull()) {
111 kDebug() << " --> Error in Textual::setVComment, invalid index!";
112 return;
115 clear_node(this_cm);
116 if(!comment.isEmpty()) {
117 this_cm.appendChild(document.createTextNode(comment));
118 this_cm.appendChild(document.createTextNode(QString(" ")));
122 void Textual::remove(const Index& index) {
123 DOM::HTMLDocument document = htmlDocument();
124 if(index.atVariationStart()) {
125 DOM::Element vc = document.getElementById("vc_"+index);
126 if(!vc.isNull()) {
127 /* remove a number? */
128 DOM::Element comm(vc.previousSibling());
129 DOM::Element mvnum(vc.nextSibling());
130 if(!mvnum.isNull() && mvnum.getAttribute("id").string().startsWith("nm_") &&
131 !comm.isNull() && comm.getAttribute("id").string().startsWith("cm_"))
133 DOM::Element move(mvnum.nextSibling());
134 int mv_num = move.getAttribute("mvnum").string().toInt();
135 int sub_mv_num = move.getAttribute("submvnum").string().toInt();
136 if(!(mv_num>0 && (sub_mv_num==0 && (mv_num%2 || m_layout_style))))
137 mvnum.parentNode().removeChild(mvnum);
139 vc.parentNode().removeChild(vc);
142 else {
143 DOM::Element rm = document.getElementById("nm_"+index);
144 if(rm.isNull())
145 rm = document.getElementById("mv_"+index);
146 if(!rm.isNull())
147 clear_from(rm);
149 if(m_curr_selected >= index)
150 m_curr_selected = Index(-1);
153 void Textual::select(const Index& index) {
154 if(index == m_curr_selected)
155 return;
156 DOM::HTMLDocument document = htmlDocument();
157 DOM::Element currs = document.getElementById("mv_"+m_curr_selected);
158 DOM::Element news = document.getElementById("mv_"+index);
159 if(!currs.isNull())
160 currs.style().removeProperty("background-color");
161 if(!news.isNull())
162 news.style().setProperty("background-color", "#C0E0FF", "important");
163 m_curr_selected = index;
167 void Textual::setMove(const Index& index, int turn, const QString& move,
168 const QString& comment) {
169 DecoratedMove m;
170 m << MovePart(move);
171 setMove(index, turn, m, comment);
174 // void Textual::setMove(const Index& index, int turn, const DecoratedMove& move,
175 // const QString& comment) {
176 // setMove(index, turn, move[0].m_string, comment);
177 // }
179 void Textual::setMove(const Index& index, int turn, const DecoratedMove& move,
180 const QString& comment) {
181 //kDebug() << "i= " << index;
182 DOM::HTMLDocument document = htmlDocument();
183 QString istr = (QString)index;
185 DOM::Element this_mv = document.getElementById("mv_"+istr);
186 DOM::Element this_cm = document.getElementById("cm_"+istr);
187 if(!this_mv.isNull() && !this_cm.isNull()) {
188 clear_node(this_mv);
189 for(int i=0;i<move.size();i++) {
190 DOM::Text t = document.createTextNode(move[i].m_string);
191 this_mv.appendChild(t);
194 clear_node(this_cm);
195 if(!comment.isEmpty()) {
196 this_cm.appendChild(document.createTextNode(comment));
197 this_cm.appendChild(document.createTextNode(QString(" ")));
199 return;
202 DOM::Element parent;
203 DOM::Element prev_mv;
204 DOM::Element prev_cm;
206 if(index != Index(0)) {
207 prev_cm = document.getElementById("cm_"+index.prev());
208 prev_mv = document.getElementById("mv_"+index.prev());
209 if(prev_cm.isNull() || prev_mv.isNull()) {
210 kDebug() << " --> Error in Textual::setMove, no previous move!";
211 return;
215 int mv_num = 0;
216 int sub_mv_num = 0;
217 if(!prev_mv.isNull()) {
218 int prev_turn = prev_mv.getAttribute("turn").string().toInt();
219 int prev_mv_num = prev_mv.getAttribute("mvnum").string().toInt();
220 int prev_sub_mv_num = prev_mv.getAttribute("submvnum").string().toInt();
221 if(prev_turn != turn)
222 mv_num = prev_mv_num+1;
223 else {
224 mv_num = prev_mv_num;
225 sub_mv_num = prev_sub_mv_num+1;
229 if(!index.nested.size()) {
230 parent = document.body();
231 if(parent.isNull()) {
232 kDebug() << "QUEEEEEEEEE!!!!!!!";
233 return;
236 else if(index.atVariationStart()) {
237 QString var_id = "vc_" + istr;
238 DOM::Element add_before = prev_cm.nextSibling();
240 while(!add_before.isNull()) {
242 QString id = add_before.getAttribute("id").string();
243 if(id.startsWith("vc_") && id < var_id)
244 add_before = add_before.nextSibling();
245 else
246 break;
249 DOM::Element var_el = document.createElement("span");
250 var_el.setAttribute("id", var_id);
251 var_el.setAttribute("class", "variation");
252 var_el.appendChild(document.createTextNode("[ "));
255 parent = document.createElement("span");
256 parent.setAttribute("id", "vr_" + istr);
257 DOM::Element vk_el = document.createElement("span");
258 vk_el.setAttribute("id", "vk_" + istr);
259 vk_el.setAttribute("class", "comment");
260 //vk_el.setContentEditable(true);
261 parent.appendChild(vk_el);
262 var_el.appendChild(parent);
264 var_el.appendChild(document.createTextNode("] "));
265 prev_cm.parentNode().insertBefore(var_el, add_before);
267 if(!add_before.isNull() && add_before.getAttribute("id").string().startsWith("mv_")) {
268 int mv_num = add_before.getAttribute("mvnum").string().toInt();
269 int sub_mv_num = add_before.getAttribute("submvnum").string().toInt();
270 QString num_str;
271 if(m_layout_style == 0) {
272 if(mv_num%2)
273 num_str = QString("%1. ").arg((mv_num+1)/2);
274 else
275 num_str = QString("%1. ... ").arg((mv_num+2)/2);
277 else {
278 if(sub_mv_num==0)
279 num_str = QString("%1. ").arg(mv_num);
280 else
281 num_str = QString("%1+%2. ").arg(mv_num).arg(sub_mv_num);
283 DOM::Element num_el = document.createElement("a");
284 num_el.setAttribute("class", "mvnum");
285 num_el.setAttribute("id", "nm_"+istr);
286 num_el.appendChild(document.createTextNode(num_str));
287 prev_cm.parentNode().insertBefore(num_el, add_before);
290 else {
291 Index pi = index.prev(index.nested.back().num_moves);
292 parent = document.getElementById("vr_"+pi);
293 if(parent.isNull()) {
294 kDebug() << " --> Error in Textual::setMove, no variation?!?!?";
295 return;
299 if(mv_num>0 && ((sub_mv_num==0 && (mv_num%2 || m_layout_style)) || parent.lastChild() != prev_cm) ) {
300 QString num_str;
301 if(m_layout_style == 0) {
302 if(mv_num%2)
303 num_str = QString("%1. ").arg((mv_num+1)/2);
304 else
305 num_str = QString("%1. ... ").arg((mv_num+2)/2);
307 else {
308 if(sub_mv_num==0)
309 num_str = QString("%1. ").arg(mv_num);
310 else
311 num_str = QString("%1+%2. ").arg(mv_num).arg(sub_mv_num);
313 DOM::Element num_el = document.createElement("a");
314 num_el.setAttribute("class", "mvnum");
315 num_el.setAttribute("id", "nm_"+istr);
316 num_el.appendChild(document.createTextNode(num_str));
317 parent.appendChild(num_el);
320 DOM::Element mv_el = document.createElement("a");
321 mv_el.setAttribute("id", "mv_"+istr);
322 mv_el.setAttribute("href", "index://"+istr);
323 mv_el.setAttribute("class", "move");
324 mv_el.setAttribute("turn", QString::number(turn));
325 mv_el.setAttribute("mvnum", QString::number(mv_num));
326 mv_el.setAttribute("submvnum", QString::number(sub_mv_num));
327 for(int i=0;i<move.size();i++) {
328 if(move[i].m_type == MovePart::Figurine) {
329 ::Loader::Glyph g = m_loader.getValue< ::Loader::Glyph>(move[i].m_string);
330 DOM::Element el = document.createElement("span");
331 #if 1
332 kDebug() << "size = " << QString("%1%").arg(g.m_font.pointSize()*100/12);
333 el.style().setProperty("font-size", QString("%1%").arg(g.m_font.pointSize()*100/12), "important");
334 el.style().setProperty("line-height", QString("%1%").arg(g.m_font.pointSize()*100/12), "important");
335 #endif
336 kDebug() << "familiy = " << g.m_font.family();
337 el.style().setProperty("font-weight", "normal", "important");
338 el.style().setProperty("font-family", g.m_font.family(), "important");
339 DOM::Text t = document.createTextNode(QString(g.m_char));
340 el.appendChild(t);
341 mv_el.appendChild(el);
343 else {
344 DOM::Text t = document.createTextNode(move[i].m_string);
345 mv_el.appendChild(t);
348 parent.appendChild(mv_el);
350 parent.appendChild(document.createTextNode(QString(" ")));
352 DOM::Element cm_el = document.createElement("span");
353 cm_el.setAttribute("id", "cm_"+istr);
354 cm_el.setAttribute("class", "comment");
355 if(!comment.isEmpty()) {
356 cm_el.appendChild(document.createTextNode(comment));
357 cm_el.appendChild(document.createTextNode(QString(" ")));
359 //cm_el.setContentEditable(true);
360 parent.appendChild(cm_el);
363 void Textual::reset() {
364 clear_node(htmlDocument().body());
365 setMove(0, -1, "Mainline:");
368 Notifier* Textual::getNotifier() {
369 return m_notifier;
372 void Textual::setNotifier(Notifier* n, bool detach_prev) {
373 if(detach_prev && m_notifier && m_notifier != n)
374 m_notifier->onDetachNotifier();
375 m_notifier = n;
378 int Textual::layoutStyle() {
379 return m_layout_style;
382 void Textual::setLayoutStyle(int x) {
383 m_layout_style = x;
387 } //end namespace MoveList
389 #endif //HAVE_KHTML