1 /**
2  * Copyright (C) 2005 by Koos Vriezen <koos.vriezen@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License version 2 as published by the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Library General Public License for more details.
12  *
13  * You should have received a copy of the GNU Library General Public License
14  * along with this library; see the file COPYING.LIB.  If not, write to
15  * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
16  * Boston, MA 02110-1301, USA.
17  **/
18 
19 #include "config-kmplayer.h"
20 #include <kdebug.h>
21 
22 #include "kmplayer_asx.h"
23 
24 #include <QUrl>
25 
26 using namespace KMPlayer;
27 
getAsxAttribute(Element * e,const QString & attr)28 static QString getAsxAttribute (Element * e, const QString & attr) {
29     for (Attribute *a = e->attributes ().first (); a; a = a->nextSibling ())
30         if (attr == a->name ().toString ().toLower ())
31             return a->value ();
32     return QString ();
33 }
34 
childFromTag(const QString & tag)35 KDE_NO_EXPORT Node *ASX::Asx::childFromTag (const QString & tag) {
36     QByteArray ba = tag.toLatin1 ();
37     const char *name = ba.constData ();
38     if (!strcasecmp (name, "entry"))
39         return new ASX::Entry (m_doc);
40     else if (!strcasecmp (name, "entryref"))
41         return new ASX::EntryRef (m_doc);
42     else if (!strcasecmp (name, "title"))
43         return new DarkNode (m_doc, name, id_node_title);
44     else if (!strcasecmp (name, "base"))
45         return new DarkNode (m_doc, name, id_node_base);
46     else if (!strcasecmp (name, "param"))
47         return new DarkNode (m_doc, name, id_node_param);
48     return 0L;
49 }
50 
role(RoleType msg,void * content)51 void *ASX::Asx::role (RoleType msg, void *content)
52 {
53     if (RolePlaylist == msg)
54         return !title.isEmpty () ? (PlaylistRole *) this : NULL;
55     return Mrl::role (msg, content);
56 }
57 
closed()58 KDE_NO_EXPORT void ASX::Asx::closed () {
59     for (Node *e = firstChild (); e; e = e->nextSibling ()) {
60         if (e->id == id_node_title)
61             title = e->innerText ().simplified ();
62         else if (e->id == id_node_base)
63             src = getAsxAttribute (static_cast <Element *> (e), "href");
64     }
65 }
66 
67 //-----------------------------------------------------------------------------
68 
childFromTag(const QString & tag)69 KDE_NO_EXPORT Node *ASX::Entry::childFromTag (const QString & tag) {
70     QByteArray ba = tag.toLatin1 ();
71     const char *name = ba.constData ();
72     if (!strcasecmp (name, "ref"))
73         return new ASX::Ref (m_doc);
74     else if (!strcasecmp (name, "title"))
75         return new DarkNode (m_doc, name, id_node_title);
76     else if (!strcasecmp (name, "base"))
77         return new DarkNode (m_doc, name, id_node_base);
78     else if (!strcasecmp (name, "param"))
79         return new DarkNode (m_doc, name, id_node_param);
80     else if (!strcasecmp (name, "starttime"))
81         return new DarkNode (m_doc, name, id_node_starttime);
82     else if (!strcasecmp (name, "duration"))
83         return new DarkNode (m_doc, name, id_node_duration);
84     return 0L;
85 }
86 
playType()87 KDE_NO_EXPORT Node::PlayType ASX::Entry::playType () {
88     return play_type_none;
89 }
90 
closed()91 KDE_NO_EXPORT void ASX::Entry::closed () {
92     ref_child_count = 0;
93     Node *ref = NULL;
94     for (Node *e = firstChild (); e; e = e->nextSibling ()) {
95         switch (e->id) {
96         case id_node_title:
97             title = e->innerText (); // already normalized (hopefully)
98             break;
99         case id_node_base:
100             src = getAsxAttribute (static_cast <Element *> (e), "href");
101             break;
102         case id_node_ref:
103             ref = e;
104             ref_child_count++;
105         }
106     }
107     if (ref_child_count == 1 && !title.isEmpty ())
108         static_cast <ASX::Ref *> (ref)->title = title;
109 }
110 
activate()111 KDE_NO_EXPORT void ASX::Entry::activate () {
112     resolved = true;
113     for (Node *e = firstChild (); e; e = e->nextSibling ())
114         if (e->id == id_node_param) {
115             Element * elm = static_cast <Element *> (e);
116             if (getAsxAttribute(elm,"name").toLower() == QString("clipsummary")) {
117                 QString inf = QUrl::fromPercentEncoding (
118                                 getAsxAttribute (elm, "value").toUtf8 ());
119                 document ()->message (MsgInfoString, &inf);
120             }
121         } else if (e->id == id_node_duration) {
122             QString s = static_cast <Element *> (e)->getAttribute (
123                     Ids::attr_value);
124             int pos = parseTimeString( s );
125             if (pos > 0)
126                 duration_timer = document()->post (
127                         this, new TimerPosting (pos * 10));
128         }
129     Mrl::activate ();
130 }
131 
message(MessageType msg,void * content)132 KDE_NO_EXPORT void ASX::Entry::message (MessageType msg, void *content) {
133     if (msg == MsgEventTimer) {
134         duration_timer = NULL;
135         deactivate ();
136         return;
137     }
138     Mrl::message (msg, content);
139 }
140 
deactivate()141 KDE_NO_EXPORT void ASX::Entry::deactivate () {
142     document ()->message (MsgInfoString, NULL);
143     if (duration_timer) {
144         document()->cancelPosting (duration_timer);
145         duration_timer = NULL;
146     }
147     Mrl::deactivate ();
148 }
149 
role(RoleType msg,void * content)150 void *ASX::Entry::role (RoleType msg, void *content)
151 {
152     if (RolePlaylist == msg)
153         return ref_child_count > 1 && !title.isEmpty ()
154             ? (PlaylistRole *) this : NULL;
155     return Mrl::role (msg, content);
156 }
157 
158 //-----------------------------------------------------------------------------
159 
opened()160 KDE_NO_EXPORT void ASX::Ref::opened () {
161     src = getAsxAttribute (this, "href");
162     Mrl::opened ();
163 }
164 
165 //-----------------------------------------------------------------------------
166 
opened()167 KDE_NO_EXPORT void ASX::EntryRef::opened () {
168     src = getAsxAttribute (this, "href");
169     Mrl::opened ();
170 }
171 
172