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.
13 #include <boost/shared_ptr.hpp>
16 #include <QHBoxLayout>
17 #include <QTextStream>
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"
31 Textual::Textual(QWidget
*parent
)
32 : KHTMLPart(parent
, parent
, KHTMLPart::BrowserViewGUI
)
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;
48 file
.open(QIODevice::ReadOnly
);
49 QTextStream
stream(&file
);
50 QString html
= stream
.readAll();
51 //kDebug() << "Using HTML:"<<html;
56 setMove(0, -1, "Mainline:");
59 static void clear_node(DOM::Node n
) {
62 DOM::Node f
= n
.firstChild();
69 static void clear_from(DOM::Node n
) {
70 DOM::Node p
= n
.parentNode();
72 DOM::Node next
= n
.nextSibling();
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
<<"\"?";
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!";
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!";
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
);
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
);
143 DOM::Element rm
= document
.getElementById("nm_"+index
);
145 rm
= document
.getElementById("mv_"+index
);
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
)
156 DOM::HTMLDocument document
= htmlDocument();
157 DOM::Element currs
= document
.getElementById("mv_"+m_curr_selected
);
158 DOM::Element news
= document
.getElementById("mv_"+index
);
160 currs
.style().removeProperty("background-color");
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
) {
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);
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()) {
189 for(int i
=0;i
<move
.size();i
++) {
190 DOM::Text t
= document
.createTextNode(move
[i
].m_string
);
191 this_mv
.appendChild(t
);
195 if(!comment
.isEmpty()) {
196 this_cm
.appendChild(document
.createTextNode(comment
));
197 this_cm
.appendChild(document
.createTextNode(QString(" ")));
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!";
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;
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!!!!!!!";
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();
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();
271 if(m_layout_style
== 0) {
273 num_str
= QString("%1. ").arg((mv_num
+1)/2);
275 num_str
= QString("%1. ... ").arg((mv_num
+2)/2);
279 num_str
= QString("%1. ").arg(mv_num
);
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
);
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?!?!?";
299 if(mv_num
>0 && ((sub_mv_num
==0 && (mv_num
%2 || m_layout_style
)) || parent
.lastChild() != prev_cm
) ) {
301 if(m_layout_style
== 0) {
303 num_str
= QString("%1. ").arg((mv_num
+1)/2);
305 num_str
= QString("%1. ... ").arg((mv_num
+2)/2);
309 num_str
= QString("%1. ").arg(mv_num
);
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");
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");
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
));
341 mv_el
.appendChild(el
);
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() {
372 void Textual::setNotifier(Notifier
* n
, bool detach_prev
) {
373 if(detach_prev
&& m_notifier
&& m_notifier
!= n
)
374 m_notifier
->onDetachNotifier();
378 int Textual::layoutStyle() {
379 return m_layout_style
;
382 void Textual::setLayoutStyle(int x
) {
387 } //end namespace MoveList