File indexing completed on 2024-04-28 16:07:51
0001 /** 0002 This file belong to the KMPlayer project, a movie player plugin for Konqueror 0003 Copyright (C) 2009 Koos Vriezen <koos.vriezen@gmail.com> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Lesser General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Lesser General Public License for more details. 0014 0015 You should have received a copy of the GNU Lesser General Public 0016 License along with this library; if not, write to the Free Software 0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0018 **/ 0019 0020 #include <qfile.h> 0021 #include <qurl.h> 0022 #include <qtextstream.h> 0023 #include <qbytearray.h> 0024 #include <qinputdialog.h> 0025 #include <QStandardPaths> 0026 0027 #include <kfiledialog.h> 0028 #include <ksharedconfig.h> 0029 #include <klocalizedstring.h> 0030 #include <kdebug.h> 0031 0032 #include "kmplayer_lists.h" 0033 #include "kmplayer.h" 0034 #include "mediaobject.h" 0035 0036 0037 KDE_NO_EXPORT void ListsSource::play (KMPlayer::Mrl *mrl) { 0038 if (m_player->source () == this) 0039 Source::play (mrl); 0040 else if (mrl) 0041 mrl->activate (); 0042 } 0043 0044 KDE_NO_EXPORT void ListsSource::activate () { 0045 activated = true; 0046 play (m_current ? m_current->mrl () : NULL); 0047 } 0048 0049 QString ListsSource::prettyName () 0050 { 0051 return ((KMPlayer::PlaylistRole *)m_document->role (KMPlayer::RolePlaylist))->caption (); 0052 } 0053 0054 KDE_NO_CDTOR_EXPORT FileDocument::FileDocument (short i, const QString &s, KMPlayer::Source *src) 0055 : KMPlayer::SourceDocument (src, s), load_tree_version ((unsigned int)-1) { 0056 id = i; 0057 } 0058 0059 KDE_NO_EXPORT KMPlayer::Node *FileDocument::childFromTag(const QString &tag) { 0060 if (tag == QString::fromLatin1 (nodeName ())) 0061 return this; 0062 return 0L; 0063 } 0064 0065 void FileDocument::readFromFile (const QString & fn) { 0066 QFile file (fn); 0067 kDebug () << "readFromFile " << fn; 0068 if (QFileInfo (file).exists ()) { 0069 file.open (QIODevice::ReadOnly); 0070 QTextStream inxml (&file); 0071 inxml.setCodec("UTF-8"); 0072 KMPlayer::readXML (this, inxml, QString (), false); 0073 normalize (); 0074 } 0075 load_tree_version = m_tree_version; 0076 } 0077 0078 void FileDocument::writeToFile (const QString & fn) { 0079 QFile file (fn); 0080 kDebug () << "writeToFile " << fn; 0081 file.open (QIODevice::WriteOnly | QIODevice::Truncate); 0082 file.write (outerXML ().toUtf8 ()); 0083 load_tree_version = m_tree_version; 0084 } 0085 0086 void FileDocument::sync (const QString &fn) 0087 { 0088 if (resolved && load_tree_version != m_tree_version) 0089 writeToFile (fn); 0090 } 0091 0092 KDE_NO_CDTOR_EXPORT Recents::Recents (KMPlayerApp *a) 0093 : FileDocument (id_node_recent_document, "recents://"), 0094 app(a) { 0095 title = i18n ("Most Recent"); 0096 bookmarkable = false; 0097 } 0098 0099 KDE_NO_EXPORT void Recents::activate () { 0100 if (!resolved) 0101 defer (); 0102 } 0103 0104 KDE_NO_EXPORT void Recents::defer () { 0105 if (!resolved) { 0106 resolved = true; 0107 readFromFile(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kmplayer/recent.xml"); 0108 } 0109 } 0110 0111 KDE_NO_EXPORT KMPlayer::Node *Recents::childFromTag (const QString & tag) { 0112 // kDebug () << nodeName () << " childFromTag " << tag; 0113 if (tag == QString::fromLatin1 ("item")) 0114 return new Recent (m_doc, app); 0115 else if (tag == QString::fromLatin1 ("group")) 0116 return new Group (m_doc, app); 0117 return FileDocument::childFromTag (tag); 0118 } 0119 0120 KDE_NO_EXPORT void Recents::message (KMPlayer::MessageType msg, void *data) { 0121 if (KMPlayer::MsgChildFinished == msg) 0122 finish (); 0123 else 0124 FileDocument::message (msg, data); 0125 } 0126 0127 KDE_NO_CDTOR_EXPORT 0128 Recent::Recent (KMPlayer::NodePtr & doc, KMPlayerApp * a, const QString &url) 0129 : KMPlayer::Mrl (doc, id_node_recent_node), app (a) { 0130 src = url; 0131 setAttribute (KMPlayer::Ids::attr_url, url); 0132 } 0133 0134 KDE_NO_EXPORT void Recent::closed () { 0135 src = getAttribute (KMPlayer::Ids::attr_url); 0136 Mrl::closed (); 0137 } 0138 0139 KDE_NO_EXPORT void Recent::activate () { 0140 app->openDocumentFile (KUrl (src)); 0141 } 0142 0143 KDE_NO_CDTOR_EXPORT 0144 Group::Group (KMPlayer::NodePtr & doc, KMPlayerApp * a, const QString & pn) 0145 : KMPlayer::Element (doc, KMPlayer::id_node_group_node), app (a) { 0146 title = pn; 0147 if (!pn.isEmpty ()) 0148 setAttribute (KMPlayer::Ids::attr_title, pn); 0149 } 0150 0151 KDE_NO_EXPORT KMPlayer::Node *Group::childFromTag (const QString & tag) { 0152 if (tag == QString::fromLatin1 ("item")) 0153 return new Recent (m_doc, app); 0154 else if (tag == QString::fromLatin1 ("group")) 0155 return new Group (m_doc, app); 0156 return 0L; 0157 } 0158 0159 KDE_NO_EXPORT void Group::closed () { 0160 title = getAttribute (KMPlayer::Ids::attr_title); 0161 Element::closed (); 0162 } 0163 0164 void *Group::role (KMPlayer::RoleType msg, void *content) 0165 { 0166 if (KMPlayer::RolePlaylist == msg) 0167 return (KMPlayer::PlaylistRole *) this ; 0168 return Element::role (msg, content); 0169 } 0170 0171 KDE_NO_EXPORT void Playlist::defer () { 0172 if (playmode) { 0173 KMPlayer::Document::defer (); 0174 // Hack: Node::undefer will restart first item when state=init 0175 if (firstChild() && KMPlayer::Node::state_init == firstChild()->state) 0176 firstChild()->state = KMPlayer::Node::state_activated; 0177 } else if (!resolved) { 0178 resolved = true; 0179 readFromFile(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/kmplayer/playlist.xml"); 0180 } 0181 } 0182 0183 KDE_NO_EXPORT void Playlist::activate () { 0184 if (playmode) 0185 KMPlayer::Document::activate (); 0186 else if (!resolved) 0187 defer (); 0188 } 0189 0190 KDE_NO_CDTOR_EXPORT Playlist::Playlist (KMPlayerApp *a, KMPlayer::Source *s, bool plmode) 0191 : FileDocument (KMPlayer::id_node_playlist_document, "Playlist://", s), 0192 app(a), 0193 playmode (plmode) { 0194 title = i18n ("Persistent Playlists"); 0195 bookmarkable = false; 0196 } 0197 0198 KDE_NO_EXPORT KMPlayer::Node *Playlist::childFromTag (const QString & tag) { 0199 // kDebug () << nodeName () << " childFromTag " << tag; 0200 QByteArray ba = tag.toUtf8 (); 0201 const char *name = ba.constData (); 0202 if (!strcmp (name, "item")) 0203 return new PlaylistItem (m_doc, app, playmode); 0204 else if (!strcmp (name, "group")) 0205 return new PlaylistGroup (m_doc, app, playmode); 0206 else if (!strcmp (name, "object")) 0207 return new HtmlObject (m_doc, app, playmode); 0208 return FileDocument::childFromTag (tag); 0209 } 0210 0211 KDE_NO_EXPORT void Playlist::message (KMPlayer::MessageType msg, void *data) { 0212 if (KMPlayer::MsgChildFinished == msg && !playmode) 0213 finish (); 0214 else 0215 FileDocument::message (msg, data); 0216 } 0217 0218 KDE_NO_CDTOR_EXPORT 0219 PlaylistItemBase::PlaylistItemBase (KMPlayer::NodePtr &d, short i, KMPlayerApp *a, bool pm) 0220 : KMPlayer::Mrl (d, i), app (a), playmode (pm) { 0221 editable = !pm; 0222 } 0223 0224 KDE_NO_EXPORT void PlaylistItemBase::activate () { 0225 if (playmode) { 0226 Mrl::activate (); 0227 } else { 0228 ListsSource * source = static_cast <ListsSource *> (app->player ()->sources () ["listssource"]); 0229 Playlist *pl = new Playlist (app, source, true); 0230 KMPlayer::NodePtr n = pl; 0231 pl->src.clear (); 0232 QString data; 0233 QString pn; 0234 if (parentNode ()->id == KMPlayer::id_node_group_node) { 0235 data = QString ("<playlist>") + 0236 parentNode ()->innerXML () + 0237 QString ("</playlist>"); 0238 pn = ((KMPlayer::PlaylistRole *)parentNode ()->role (KMPlayer::RolePlaylist))->caption (); 0239 } else { 0240 data = outerXML (); 0241 pn = title.isEmpty () ? src : title; 0242 } 0243 pl->setCaption (pn); 0244 //kDebug () << "cloning to " << data; 0245 QTextStream inxml (&data, QIODevice::ReadOnly); 0246 KMPlayer::readXML (pl, inxml, QString (), false); 0247 pl->normalize (); 0248 KMPlayer::Node *cur = pl->firstChild (); 0249 pl->mrl ()->resolved = !!cur; 0250 if (parentNode ()->id == KMPlayer::id_node_group_node && cur) { 0251 KMPlayer::Node *sister = parentNode ()->firstChild (); 0252 while (sister && cur && sister != this) { 0253 sister = sister->nextSibling (); 0254 cur = cur->nextSibling (); 0255 } 0256 } 0257 bool reset_only = source == app->player ()->source (); 0258 if (reset_only) 0259 app->player ()->stop (); 0260 source->setDocument (pl, cur); 0261 if (reset_only) { 0262 source->activate (); 0263 app->setCaption (pn); 0264 } else 0265 app->player ()->setSource (source); 0266 } 0267 } 0268 0269 void PlaylistItemBase::closed () { 0270 title = getAttribute (KMPlayer::Ids::attr_title); 0271 Mrl::closed (); 0272 } 0273 0274 KDE_NO_CDTOR_EXPORT 0275 PlaylistItem::PlaylistItem (KMPlayer::NodePtr & doc, KMPlayerApp *a, bool pm, const QString &url) 0276 : PlaylistItemBase (doc, KMPlayer::id_node_playlist_item, a, pm) { 0277 src = url; 0278 setAttribute (KMPlayer::Ids::attr_url, url); 0279 } 0280 0281 KDE_NO_EXPORT void PlaylistItem::closed () { 0282 src = getAttribute (KMPlayer::Ids::attr_url); 0283 PlaylistItemBase::closed (); 0284 } 0285 0286 KDE_NO_EXPORT void PlaylistItem::begin () { 0287 if (playmode && firstChild ()) 0288 firstChild ()->activate (); 0289 else 0290 Mrl::begin (); 0291 } 0292 0293 KDE_NO_EXPORT void PlaylistItem::setNodeName (const QString & s) { 0294 bool uri = s.startsWith (QChar ('/')); 0295 if (!uri) { 0296 int p = s.indexOf ("://"); 0297 uri = p > 0 && p < 10; 0298 } 0299 if (uri) { 0300 if (title.isEmpty () || title == src) 0301 title = s; 0302 src = s; 0303 setAttribute (KMPlayer::Ids::attr_url, s); 0304 } else { 0305 title = s; 0306 setAttribute (KMPlayer::Ids::attr_title, s); 0307 } 0308 } 0309 0310 KDE_NO_CDTOR_EXPORT 0311 PlaylistGroup::PlaylistGroup (KMPlayer::NodePtr &doc, KMPlayerApp *a, const QString &pn) 0312 : KMPlayer::Element (doc, KMPlayer::id_node_group_node), app (a), playmode (false) { 0313 title = pn; 0314 editable = true; 0315 if (!pn.isEmpty ()) 0316 setAttribute (KMPlayer::Ids::attr_title, pn); 0317 } 0318 0319 KDE_NO_CDTOR_EXPORT 0320 PlaylistGroup::PlaylistGroup (KMPlayer::NodePtr &doc, KMPlayerApp *a, bool lm) 0321 : KMPlayer::Element (doc, KMPlayer::id_node_group_node), app (a), playmode (lm) { 0322 editable = !lm; 0323 } 0324 0325 KDE_NO_EXPORT KMPlayer::Node *PlaylistGroup::childFromTag (const QString &tag) { 0326 QByteArray ba = tag.toUtf8 (); 0327 const char *name = ba.constData (); 0328 if (!strcmp (name, "item")) 0329 return new PlaylistItem (m_doc, app, playmode); 0330 else if (!strcmp (name, "group")) 0331 return new PlaylistGroup (m_doc, app, playmode); 0332 else if (!strcmp (name, "object")) 0333 return new HtmlObject (m_doc, app, playmode); 0334 return 0L; 0335 } 0336 0337 KDE_NO_EXPORT void PlaylistGroup::closed () { 0338 title = getAttribute (KMPlayer::Ids::attr_title); 0339 Element::closed (); 0340 } 0341 0342 KDE_NO_EXPORT void PlaylistGroup::setNodeName (const QString &t) { 0343 title = t; 0344 setAttribute (KMPlayer::Ids::attr_title, t); 0345 } 0346 0347 void *PlaylistGroup::role (KMPlayer::RoleType msg, void *content) 0348 { 0349 if (KMPlayer::RolePlaylist == msg) 0350 return (KMPlayer::PlaylistRole *) this ; 0351 return Element::role (msg, content); 0352 } 0353 0354 KDE_NO_CDTOR_EXPORT 0355 HtmlObject::HtmlObject (KMPlayer::NodePtr &doc, KMPlayerApp *a, bool pm) 0356 : PlaylistItemBase (doc, KMPlayer::id_node_html_object, a, pm) {} 0357 0358 KDE_NO_EXPORT void HtmlObject::activate () { 0359 if (playmode) 0360 KMPlayer::Mrl::activate (); 0361 else 0362 PlaylistItemBase::activate (); 0363 } 0364 0365 KDE_NO_EXPORT void HtmlObject::closed () { 0366 for (Node *n = firstChild (); n; n = n->nextSibling ()) { 0367 if (n->id == KMPlayer::id_node_param) { 0368 KMPlayer::Element *e = static_cast <KMPlayer::Element *> (n); 0369 QString name = e->getAttribute (KMPlayer::Ids::attr_name); 0370 if (name == "type") 0371 mimetype = e->getAttribute (KMPlayer::Ids::attr_value); 0372 else if (name == "movie") 0373 src = e->getAttribute (KMPlayer::Ids::attr_value); 0374 } else if (n->id == KMPlayer::id_node_html_embed) { 0375 KMPlayer::Element *e = static_cast <KMPlayer::Element *> (n); 0376 QString type = e->getAttribute (KMPlayer::Ids::attr_type); 0377 if (!type.isEmpty ()) 0378 mimetype = type; 0379 QString asrc = e->getAttribute (KMPlayer::Ids::attr_src); 0380 if (!asrc.isEmpty ()) 0381 src = asrc; 0382 } 0383 } 0384 PlaylistItemBase::closed (); 0385 } 0386 0387 KDE_NO_EXPORT KMPlayer::Node *HtmlObject::childFromTag (const QString & tag) { 0388 QByteArray ba = tag.toUtf8 (); 0389 const char *name = ba.constData (); 0390 if (!strcasecmp (name, "param")) 0391 return new KMPlayer::DarkNode (m_doc, name, KMPlayer::id_node_param); 0392 else if (!strcasecmp (name, "embed")) 0393 return new KMPlayer::DarkNode(m_doc, name,KMPlayer::id_node_html_embed); 0394 return NULL; 0395 } 0396 0397 Generator::Generator (KMPlayerApp *a) 0398 : FileDocument (id_node_gen_document, QString (), 0399 a->player ()->sources () ["listssource"]), 0400 app (a), qprocess (NULL), data (NULL) 0401 {} 0402 0403 KMPlayer::Node *Generator::childFromTag (const QString &tag) { 0404 QByteArray ba = tag.toUtf8(); 0405 const char *ctag = ba.constData (); 0406 if (!strcmp (ctag, "generator")) 0407 return new GeneratorElement (m_doc, tag, id_node_gen_generator); 0408 return NULL; 0409 } 0410 0411 QString Generator::genReadAsk (KMPlayer::Node *n) { 0412 QString title; 0413 QString desc; 0414 QString type = static_cast <Element *> (n)->getAttribute ( 0415 KMPlayer::Ids::attr_type); 0416 QString key = static_cast<Element*>(n)->getAttribute ("key"); 0417 QString def = static_cast<Element*>(n)->getAttribute ("default"); 0418 QString input; 0419 KConfigGroup cfg(KSharedConfig::openConfig(), "Generator Defaults"); 0420 if (!key.isEmpty ()) 0421 def = cfg.readEntry (key, def); 0422 if (type == "file") { 0423 input = KFileDialog::getOpenFileName (KUrl (def), QString(), app); 0424 } else if (type == "dir") { 0425 input = KFileDialog::getExistingDirectoryUrl (KUrl (def), app).toLocalFile (); 0426 if (!input.isEmpty ()) 0427 input += QChar ('/'); 0428 } else { 0429 for (KMPlayer::Node *c = n->firstChild (); c; c = c->nextSibling ()) 0430 switch (c->id) { 0431 case id_node_gen_title: 0432 title = c->innerText ().simplified (); 0433 break; 0434 case id_node_gen_description: 0435 desc = c->innerText ().simplified (); 0436 break; 0437 } 0438 input = QInputDialog::getText(0, title, desc, QLineEdit::Normal, def); 0439 } 0440 if (input.isNull ()) 0441 canceled = true; 0442 else if (!key.isEmpty ()) 0443 cfg.writeEntry (key, input); 0444 return input; 0445 } 0446 0447 QString Generator::genReadUriGet (KMPlayer::Node *n) { 0448 QString str; 0449 bool first = true; 0450 for (KMPlayer::Node *c = n->firstChild (); c && !canceled; c = c->nextSibling ()) { 0451 QString key; 0452 QString val; 0453 switch (c->id) { 0454 case id_node_gen_http_key_value: { 0455 KMPlayer::Node *q = c->firstChild (); 0456 if (q) { 0457 key = genReadString (q); 0458 q = q->nextSibling (); 0459 if (q && !canceled) 0460 val = genReadString (q); 0461 } 0462 break; 0463 } 0464 default: 0465 key = genReadString (c); 0466 break; 0467 } 0468 if (!key.isEmpty ()) { 0469 if (first) { 0470 str += QChar ('?'); 0471 first = false; 0472 } else { 0473 str += QChar ('&'); 0474 } 0475 str += QUrl::toPercentEncoding (key); 0476 if (!val.isEmpty ()) 0477 str += QChar ('=') + QString (QUrl::toPercentEncoding (val)); 0478 } 0479 } 0480 return str; 0481 } 0482 0483 QString Generator::genReadString (KMPlayer::Node *n) { 0484 QString str; 0485 bool need_quote = quote; 0486 bool find_resource = false; 0487 quote = false; 0488 for (KMPlayer::Node *c = n->firstChild (); c && !canceled; c = c->nextSibling ()) 0489 switch (c->id) { 0490 case id_node_gen_uri: 0491 case id_node_gen_sequence: 0492 str += genReadString (c); 0493 break; 0494 case id_node_gen_literal: 0495 str += c->innerText ().simplified (); 0496 break; 0497 case id_node_gen_predefined: { 0498 QString val = static_cast <Element *>(c)->getAttribute ("key"); 0499 if (val == "data" || val == "sysdata") { 0500 str += "kmplayer"; 0501 find_resource = true; 0502 } 0503 break; 0504 } 0505 case id_node_gen_http_get: 0506 str += genReadUriGet (c); 0507 break; 0508 case id_node_gen_ask: 0509 str += genReadAsk (c); 0510 break; 0511 case KMPlayer::id_node_text: 0512 str += c->nodeValue ().simplified (); 0513 } 0514 if (find_resource) 0515 str = QStandardPaths::locate(QStandardPaths::GenericDataLocation, str); 0516 if (!static_cast <Element *>(n)->getAttribute ("encoding").isEmpty ()) 0517 str = QUrl::toPercentEncoding (str); 0518 if (need_quote) { 0519 //from QProcess' parseCombinedArgString 0520 str.replace (QChar ('"'), QString ("\"\"\"")); 0521 str = QChar ('"') + str + QChar ('"'); 0522 quote = true; 0523 } 0524 return str; 0525 } 0526 0527 QString Generator::genReadInput (KMPlayer::Node *n) { 0528 quote = false; 0529 return genReadString (n); 0530 } 0531 0532 QString Generator::genReadProcess (KMPlayer::Node *n) { 0533 QString process; 0534 QString str; 0535 quote = true; 0536 for (KMPlayer::Node *c = n->firstChild (); c && !canceled; c = c->nextSibling ()) 0537 switch (c->id) { 0538 case id_node_gen_program: 0539 process = QString (genReadString (c)); 0540 break; 0541 case id_node_gen_argument: 0542 process += QChar (' ') + genReadString (c); 0543 break; 0544 } 0545 return process; 0546 } 0547 0548 void Generator::activate () { 0549 QString input; 0550 canceled = false; 0551 KMPlayer::Node *n = firstChild (); 0552 if (n && n->id == id_node_gen_generator) { 0553 title = static_cast<Element *>(n)->getAttribute ( 0554 KMPlayer::Ids::attr_name); 0555 for (KMPlayer::Node *c = n->firstChild (); c && !canceled; c = c->nextSibling ()) 0556 switch (c->id) { 0557 case id_node_gen_input: 0558 input = genReadInput (c); 0559 break; 0560 case id_node_gen_process: 0561 process = genReadProcess (c); 0562 } 0563 } 0564 if (canceled) 0565 return; 0566 if (!input.isEmpty () && process.isEmpty ()) { 0567 message (KMPlayer::MsgInfoString, &input); 0568 //openFile (m_control->m_app, input); 0569 } else if (!process.isEmpty ()) { 0570 data = new QTextStream (&buffer); 0571 if (input.isEmpty ()) { 0572 message (KMPlayer::MsgInfoString, &process); 0573 begin (); 0574 } else { 0575 QString cmdline (input + " | " + process); 0576 message (KMPlayer::MsgInfoString, &cmdline); 0577 if (!media_info) 0578 media_info = new KMPlayer::MediaInfo ( 0579 this, KMPlayer::MediaManager::Data); 0580 state = state_activated; 0581 media_info->wget (input); 0582 } 0583 } 0584 } 0585 0586 void Generator::begin () { 0587 if (!qprocess) { 0588 qprocess = new QProcess (app); 0589 connect (qprocess, SIGNAL (started ()), 0590 this, SLOT (started ())); 0591 connect (qprocess, SIGNAL (error (QProcess::ProcessError)), 0592 this, SLOT (error (QProcess::ProcessError))); 0593 connect (qprocess, SIGNAL (finished (int, QProcess::ExitStatus)), 0594 this, SLOT (finished ())); 0595 connect (qprocess, SIGNAL (readyReadStandardOutput ()), 0596 this, SLOT (readyRead ())); 0597 } 0598 QString info; 0599 if (media_info) 0600 info = QString ("Input data ") + 0601 QString::number (media_info->rawData ().size () / 1024.0) + "kb | "; 0602 info += process; 0603 message (KMPlayer::MsgInfoString, &info); 0604 kDebug() << process; 0605 qprocess->start (process); 0606 state = state_began; 0607 } 0608 0609 void Generator::deactivate () { 0610 if (qprocess) { 0611 disconnect (qprocess, SIGNAL (started ()), 0612 this, SLOT (started ())); 0613 disconnect (qprocess, SIGNAL (error (QProcess::ProcessError)), 0614 this, SLOT (error (QProcess::ProcessError))); 0615 disconnect (qprocess, SIGNAL (finished (int, QProcess::ExitStatus)), 0616 this, SLOT (finished ())); 0617 disconnect (qprocess, SIGNAL (readyReadStandardOutput ()), 0618 this, SLOT (readyRead ())); 0619 qprocess->kill (); 0620 qprocess->deleteLater (); 0621 } 0622 qprocess = NULL; 0623 delete data; 0624 data = NULL; 0625 buffer.clear (); 0626 FileDocument::deactivate (); 0627 } 0628 0629 void Generator::message (KMPlayer::MessageType msg, void *content) { 0630 if (KMPlayer::MsgMediaReady == msg) { 0631 if (!media_info->rawData ().size ()) { 0632 QString err ("No input data received"); 0633 message (KMPlayer::MsgInfoString, &err); 0634 deactivate (); 0635 } else { 0636 begin (); 0637 } 0638 } else { 0639 FileDocument::message (msg, content); 0640 } 0641 } 0642 0643 void Generator::readyRead () { 0644 if (qprocess->bytesAvailable ()) 0645 *data << qprocess->readAll(); 0646 if (qprocess->state () == QProcess::NotRunning) { 0647 if (!buffer.isEmpty ()) { 0648 Playlist *pl = new Playlist (app, m_source, true); 0649 KMPlayer::NodePtr n = pl; 0650 pl->src.clear (); 0651 QTextStream stream (&buffer, QIODevice::ReadOnly); 0652 KMPlayer::readXML (pl, stream, QString (), false); 0653 pl->title = title; 0654 pl->normalize (); 0655 message (KMPlayer::MsgInfoString, NULL); 0656 bool reset_only = m_source == app->player ()->source (); 0657 if (reset_only) 0658 app->player ()->stop (); 0659 m_source->setDocument (pl, pl); 0660 if (reset_only) { 0661 m_source->activate (); 0662 app->setCaption (getAttribute(KMPlayer::Ids::attr_name)); 0663 } else { 0664 app->player ()->setSource (m_source); 0665 } 0666 } else { 0667 QString err ("No data received"); 0668 message (KMPlayer::MsgInfoString, &err); 0669 } 0670 deactivate (); 0671 } 0672 } 0673 0674 void Generator::started () { 0675 if (media_info) { 0676 QByteArray &ba = media_info->rawData (); 0677 // TODO validate utf8 0678 if (ba.size ()) 0679 qprocess->write (ba); 0680 qprocess->closeWriteChannel (); 0681 return; 0682 } 0683 message (KMPlayer::MsgInfoString, &process); 0684 } 0685 0686 void Generator::error (QProcess::ProcessError err) { 0687 kDebug () << (int)err; 0688 QString msg ("Couldn't start process"); 0689 message (KMPlayer::MsgInfoString, &msg); 0690 deactivate (); 0691 } 0692 0693 void Generator::finished () { 0694 if (active () && state_deferred != state) 0695 readyRead (); 0696 } 0697 0698 struct GeneratorTag { 0699 const char *tag; 0700 short id; 0701 } gen_tags[] = { 0702 { "input", id_node_gen_input }, 0703 { "process", id_node_gen_process }, 0704 { "uri", id_node_gen_uri }, 0705 { "literal", id_node_gen_literal }, 0706 { "ask", id_node_gen_ask }, 0707 { "title", id_node_gen_title }, 0708 { "description", id_node_gen_description }, 0709 { "process", id_node_gen_process }, 0710 { "program", id_node_gen_program }, 0711 { "argument", id_node_gen_argument }, 0712 { "predefined", id_node_gen_predefined }, 0713 { "http-get", id_node_gen_http_get }, 0714 { "key-value", id_node_gen_http_key_value }, 0715 { "key", id_node_gen_sequence }, 0716 { "value", id_node_gen_sequence }, 0717 { "sequence", id_node_gen_sequence }, 0718 { NULL, -1 } 0719 }; 0720 0721 KMPlayer::Node *GeneratorElement::childFromTag (const QString &tag) { 0722 QByteArray ba = tag.toUtf8(); 0723 const char *ctag = ba.constData (); 0724 for (GeneratorTag *t = gen_tags; t->tag; ++t) 0725 if (!strcmp (ctag, t->tag)) 0726 return new GeneratorElement (m_doc, tag, t->id); 0727 return NULL; 0728 } 0729