[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: extragear/multimedia/kmplayer
From: Koos Vriezen <koos.vriezen () gmail ! com>
Date: 2009-08-31 21:32:57
Message-ID: 1251754377.259868.17338.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 1017918 by vriezen:
Add support for setting and reading state attributes
M +85 -48 src/expression.cpp
M +17 -1 src/expression.h
M +29 -12 src/kmplayer_smil.cpp
M +16 -0 tests/state.smil
--- trunk/extragear/multimedia/kmplayer/src/expression.cpp #1017917:1017918
@@ -27,18 +27,25 @@
using namespace KMPlayer;
+QString NodeValue::value () const {
+ if (attr)
+ return attr->value ();
+ return node->nodeValue ();
+}
+
namespace {
struct EvalState {
EvalState (EvalState *p)
- : root (NULL), process_list (NULL), parent (p),
+ : root (NULL), attr (NULL), process_list (NULL), parent (p),
sequence (1), ref_count (0) {}
void addRef () { ++ref_count; }
void removeRef () { if (--ref_count == 0) delete this; }
Node *root;
- NodeRefList *process_list;
+ Attribute *attr;
+ NodeValueList *process_list;
EvalState *parent;
int sequence;
int ref_count;
@@ -56,9 +63,10 @@
virtual int toInt () const;
virtual float toFloat () const;
virtual QString toString () const;
- virtual NodeRefList *toNodeList () const;
+ virtual NodeValueList *toNodeList () const;
virtual Type type () const;
virtual void setRoot (Node *root);
+ void setRoot (Node *root, Attribute *a);
#ifdef KMPLAYER_EXPR_DEBUG
virtual void dump () const;
#endif
@@ -135,21 +143,24 @@
};
struct Step : public StringBase {
- Step (EvalState *ev) : StringBase (ev), any_path (false) {}
- Step (EvalState *ev, const char *s, const char *e)
- : StringBase (ev, s, e), any_path (string == "*") {}
+ Step (EvalState *ev) : StringBase (ev), any_node (false), is_attr (false) {}
+ Step (EvalState *ev, const char *s, const char *e, bool isattr=false)
+ : StringBase (ev, s, e), any_node (string == "*"), is_attr (isattr) {}
bool matches (Node *n);
- bool selected (Node *n);
+ bool matches (Attribute *a);
+ bool selected (Node *n, Attribute *a);
bool anyPath () const { return string.isEmpty (); }
#ifdef KMPLAYER_EXPR_DEBUG
virtual void dump () const {
- fprintf (stderr, "Step %s", string.toAscii ().data ());
+ fprintf (stderr, "Step %c%s",
+ is_attr ? '@' : ' ',string.toAscii ().data ());
AST::dump();
}
#endif
- bool any_path;
+ bool any_node;
+ bool is_attr;
};
struct Identifier : public StringBase {
@@ -159,9 +170,8 @@
virtual bool toBool () const;
virtual QString toString () const;
- virtual NodeRefList *toNodeList () const;
+ virtual NodeValueList *toNodeList () const;
virtual Type type () const;
- bool childByPath (Node *node, Step *path, NodeRefList *lst) const;
void childByStep (Step *step, bool recurse) const;
void childByPath (Step *step, bool recurse) const;
#ifdef KMPLAYER_EXPR_DEBUG
@@ -364,8 +374,8 @@
}
}
-NodeRefList *AST::toNodeList () const {
- return new NodeRefList;
+NodeValueList *AST::toNodeList () const {
+ return new NodeValueList;
}
AST::Type AST::type () const {
@@ -374,9 +384,15 @@
void AST::setRoot (Node *root) {
eval_state->root = root;
+ eval_state->attr = NULL;
eval_state->sequence++;
}
+void AST::setRoot (Node *root, Attribute *a) {
+ setRoot (root);
+ eval_state->attr = a;
+}
+
#ifdef KMPLAYER_EXPR_DEBUG
void AST::dump () const {
if (first_child) {
@@ -422,13 +438,13 @@
bool NumberBase::toBool () const {
int ii = toInt ();
if (eval_state->parent) {
- NodeRefList *lst = eval_state->parent->process_list;
- Node *r = eval_state->root;
+ NodeValueList *lst = eval_state->parent->process_list;
if (lst) {
int count = 0;
- for (NodeRefItem *n = lst->first (); n; n = n->nextSibling ())
+ for (NodeValueItem *n = lst->first (); n; n = n->nextSibling ())
if (ii == ++count)
- return r == n->data.ptr ();
+ return eval_state->root == n->data.node &&
+ eval_state->attr == n->data.attr;
}
return false;
}
@@ -480,12 +496,16 @@
}
bool Step::matches (Node *n) {
- return any_path || string == n->nodeName ();
+ return any_node || string == n->nodeName ();
}
-bool Step::selected (Node *n) {
+bool Step::matches (Attribute *a) {
+ return any_node || string == a->name ();
+}
+
+bool Step::selected (Node *n, Attribute *a) {
if (first_child) {
- first_child->setRoot (n);
+ first_child->setRoot (n, a);
return first_child->toBool ();
}
return true;
@@ -495,7 +515,7 @@
bool b = false;
if (eval_state->parent) {
sequence = eval_state->sequence;
- NodeRefList *lst = toNodeList ();
+ NodeValueList *lst = toNodeList ();
b = lst && lst->first ();
delete lst;
} else {
@@ -505,25 +525,39 @@
}
void Identifier::childByStep (Step *step, bool recurse) const {
- NodeRefList *lst = eval_state->process_list;
- NodeRefItem *last = lst->last ();
- NodeRefList recursive_lst;
- for (NodeRefItem *itm = lst->first (); itm; ) {
- NodeRefItem *next = itm == last ? NULL : itm->nextSibling ();
- for (Node *c = itm->data->firstChild (); c; c = c->nextSibling ()) {
- if (step->matches (c))
- lst->append (new NodeRefItem (c));
+ NodeValueList *lst = eval_state->process_list;
+ NodeValueItem *last = lst->last ();
+ NodeValueList recursive_lst;
+ for (NodeValueItem *itm = lst->first (); itm; ) {
+ NodeValueItem *next = itm == last ? NULL : itm->nextSibling ();
+
+ Node *n = itm->data.node;
+ if (step->is_attr) {
+ Element *e = n->isElementNode() ? static_cast<Element *> (n) : NULL;
+ Attribute *a = e ? e->attributes ().first () : NULL;
+ for (; a; a = a->nextSibling ())
+ if (step->matches (a))
+ lst->append (new NodeValueItem (NodeValue (n, a)));
if (recurse)
- recursive_lst.append (new NodeRefItem (c));
+ for (Node *c = n->firstChild(); c; c = c->nextSibling ())
+ recursive_lst.append (new NodeValueItem (c));
+ } else {
+ for (Node *c = n->firstChild(); c; c = c->nextSibling ()) {
+ if (step->matches (c))
+ lst->append (new NodeValueItem (c));
+ if (recurse)
+ recursive_lst.append (new NodeValueItem (c));
+ }
}
+
lst->remove (itm);
itm = next;
}
if (recurse && recursive_lst.first ()) {
eval_state->process_list = &recursive_lst;
childByStep (step, recurse);
- for (NodeRefItem *r = recursive_lst.first (); r; r = r->nextSibling ())
- lst->append (new NodeRefItem (r->data));
+ for (NodeValueItem *r = recursive_lst.first (); r; r = r->nextSibling ())
+ lst->append (new NodeValueItem (r->data));
eval_state->process_list = lst;
}
}
@@ -531,12 +565,12 @@
void Identifier::childByPath (Step *step, bool recurse) const {
if (!step->anyPath ()) {
childByStep (step, recurse);
- NodeRefItem *itm = eval_state->process_list->first ();
+ NodeValueItem *itm = eval_state->process_list->first ();
if (itm && step->first_child) {
- NodeRefList *newlist = new NodeRefList;
+ NodeValueList *newlist = new NodeValueList;
for (; itm; itm = itm->nextSibling ())
- if (step->selected (itm->data))
- newlist->append (new NodeRefItem (itm->data));
+ if (step->selected (itm->data.node, itm->data.attr))
+ newlist->append (new NodeValueItem (itm->data));
delete eval_state->process_list;
eval_state->process_list = newlist;
}
@@ -547,10 +581,10 @@
QString Identifier::toString () const {
if (eval_state->sequence != sequence) {
- NodeRefList *lst = toNodeList ();
+ NodeValueList *lst = toNodeList ();
int i = lst->length ();
if (i == 1)
- string = lst->first ()->data->nodeValue ();
+ string = lst->first ()->data.value ();
else
string = QString::number (i);
delete lst;
@@ -559,11 +593,11 @@
return string;
}
-NodeRefList *Identifier::toNodeList () const {
- NodeRefList *old = eval_state->process_list;
- NodeRefList *lst = new NodeRefList;
+NodeValueList *Identifier::toNodeList () const {
+ NodeValueList *old = eval_state->process_list;
+ NodeValueList *lst = new NodeValueList;
eval_state->process_list = lst;
- lst->append (new NodeRefItem (eval_state->root));
+ lst->append (new NodeValueItem (eval_state->root));
childByPath ((Step *) first_child, false);
lst = eval_state->process_list;
eval_state->process_list = old;
@@ -645,7 +679,7 @@
if (eval_state->sequence != sequence) {
sequence = eval_state->sequence;
if (eval_state->parent) {
- NodeRefList *lst = eval_state->parent->process_list;
+ NodeValueList *lst = eval_state->parent->process_list;
if (lst)
i = lst->length ();
}
@@ -666,13 +700,13 @@
if (eval_state->sequence != sequence) {
sequence = eval_state->sequence;
if (eval_state->parent) {
- NodeRefList *lst = eval_state->parent->process_list;
+ NodeValueList *lst = eval_state->parent->process_list;
Node *r = eval_state->root;
if (lst) {
i = 0;
- for (NodeRefItem *n = lst->first(); n; n = n->nextSibling ()) {
+ for (NodeValueItem *n = lst->first(); n; n = n->nextSibling()) {
i++;
- if (r == n->data.ptr ())
+ if (r == n->data.node)
break;
}
}
@@ -864,7 +898,7 @@
case gteq:
return first_child->toInt () >= first_child->next_sibling->toInt ();
case eq:
- if (t1 == t2 && t1 == AST::TString)
+ if (t1 == AST::TString || t2 == AST::TString)
return first_child->toString () ==
first_child->next_sibling->toString ();
return first_child->toInt () == first_child->next_sibling->toInt ();
@@ -998,6 +1032,9 @@
if (*s == '/') {
entry = new Step (ast->eval_state);
} else {
+ bool is_attr = *s == '@';
+ if (is_attr)
+ s = ++str;
for (; *s; ++s)
if (!((*s >= 'a' && *s <= 'z') ||
(*s >= 'A' && *s <= 'Z') ||
@@ -1007,7 +1044,7 @@
break;
if (str == s)
return false;
- entry = new Step (ast->eval_state, str, s);
+ entry = new Step (ast->eval_state, str, s, is_attr);
if (*s == '[') {
AST pred (new EvalState (ast->eval_state));
if (parseStatement (s + 1, end, &pred)) {
--- trunk/extragear/multimedia/kmplayer/src/expression.h #1017917:1017918
@@ -24,13 +24,29 @@
namespace KMPlayer {
+class NodeValue {
+public:
+ NodeValue (Node *n, Attribute *a=NULL) : node (n), attr (a) {}
+
+ QString value () const;
+
+ Node *node;
+ Attribute *attr;
+};
+
+typedef ListNode<NodeValue> NodeValueItem;
+ITEM_AS_POINTER(KMPlayer::NodeValueItem)
+typedef NodeValueItem::SharedType NodeValueItemPtr;
+typedef List <NodeValueItem> NodeValueList;
+
+
class Expression : public VirtualVoid {
public:
virtual bool toBool () const = 0;
virtual int toInt () const = 0;
virtual float toFloat () const = 0;
virtual QString toString () const = 0;
- virtual NodeRefList *toNodeList () const = 0;
+ virtual NodeValueList *toNodeList () const = 0;
virtual void setRoot (Node *root) = 0;
};
--- trunk/extragear/multimedia/kmplayer/src/kmplayer_smil.cpp #1017917:1017918
@@ -1371,9 +1371,9 @@
if (c->payload && c->connecter) {
Expression *expr = (Expression *) c->payload;
expr->setRoot (s);
- NodeRefList *lst = expr->toNodeList ();
- for (NodeRefItem *itm = lst->first(); itm; itm = itm->nextSibling())
- if (itm->data.ptr () == ref)
+ NodeValueList *lst = expr->toNodeList ();
+ for (NodeValueItem *itm = lst->first(); itm; itm = itm->nextSibling())
+ if (itm->data.node == ref)
s->document()->post (c->connecter,
new Posting (s, MsgStateChanged));
delete lst;
@@ -4154,9 +4154,15 @@
if (!ref)
ref = evaluateExpr ("/data");
ref->setRoot (st);
- NodeRefList *lst = ref->toNodeList ();
- if (lst->first ())
- st->newValue (lst->first ()->data, where, name, value);
+ NodeValueList *lst = ref->toNodeList ();
+ NodeValueItem *itm = lst->first ();
+ if (itm) {
+ if (name.startsWith(QChar('@')) && itm->data.node->isElementNode())
+ static_cast <Element *> (itm->data.node)->setAttribute (
+ name.mid (1), value);
+ else
+ st->newValue (itm->data.node, where, name, value);
+ }
delete lst;
}
}
@@ -4184,9 +4190,15 @@
kWarning () << "ref is empty or no state";
} else {
ref->setRoot (st);
- NodeRefList *lst = ref->toNodeList ();
- if (lst->first ())
- st->setValue (lst->first ()->data, value);
+ NodeValueList *lst = ref->toNodeList ();
+ NodeValueItemPtr itm = lst->first ();
+ if (itm) {
+ if (itm->data.attr && itm->data.node->isElementNode ())
+ static_cast <Element *> (itm->data.node)->setAttribute (
+ itm->data.attr->name (), itm->data.attr->value ());
+ else
+ st->setValue (itm->data.node, value);
+ }
delete lst;
}
}
@@ -4199,9 +4211,14 @@
kWarning () << "ref is empty or no state";
} else {
ref->setRoot (st);
- NodeRefList *lst = ref->toNodeList ();
- for (NodeRefItem *itm = lst->first (); itm; itm = itm->nextSibling ())
- itm->data->parentNode ()->removeChild (itm->data);
+ NodeValueList *lst = ref->toNodeList ();
+ for (NodeValueItem *itm = lst->first(); itm; itm = itm->nextSibling()) {
+ if (itm->data.attr && itm->data.node->isElementNode ())
+ static_cast <Element *> (itm->data.node)->setAttribute (
+ itm->data.attr->name (), QString ());
+ else
+ itm->data.node->parentNode ()->removeChild (itm->data.node);
+ }
delete lst;
}
}
--- trunk/extragear/multimedia/kmplayer/tests/state.smil #1017917:1017918
@@ -40,6 +40,22 @@
<text src="data:,books%20{number(/data/books/book)}"
left="10" top="160" width="300" height="20"/>
</par>
+ <newvalue name="@price" ref="/data/books/book[1]" value="10p"/>
+ <newvalue name="@foo" ref="/data/books/book[2]" value="fred"/>
+ <newvalue name="@bar" ref="/data/books/book[2]" value="barney"/>
+ <newvalue name="@price" ref="/data/books/book[3]" value="5$"/>
+ <par dur="5">
+ <text src="data:,books%20with%20price%20{//book[@price]}" left="10" top="10" \
width="300" height="20"/> + <text \
src="data:,books%20with%20price%2010p%20{//book[@price="10p"]/title}" \
left="10" top="40" width="300" height="20"/> + <text \
src="data:,price%20of%20Pygmalion%20{//book[title="Pygmalion"]/@price}" \
left="10" top="70" width="300" height="20"/> + <text \
src="data:,attributes%20on%20second%20book%20{//book[2]/@*}" left="10" top="100" \
width="300" height="20"/> + <text \
src="data:,total%20attributes%20on%20book%20{//book/@*}" left="10" top="130" \
width="300" height="20"/> + <text \
src="data:,second%20attribute%20on%20book%20{//book/@*[2]}" left="10" top="160" \
width="300" height="20"/> + </par>
+ <delvalue ref="//@foo"/>
+ <par dur="5">
+ <text src="data:,second%20attribute%20on%20book%20{//book/@*[2]}" left="10" \
top="160" width="300" height="20"/> + </par>
<delvalue ref="//books"/>
</body>
</smil>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic