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