File indexing completed on 2024-04-14 15:00:58
0001 /** 0002 * Copyright (C) 2002-2003 by Koos Vriezen <koos.vriezen@gmail.com> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Library General Public 0006 * License version 2 as published by the Free Software Foundation. 0007 * 0008 * This library is distributed in the hope that it will be useful, 0009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0011 * Library General Public License for more details. 0012 * 0013 * You should have received a copy of the GNU Library General Public License 0014 * along with this library; see the file COPYING.LIB. If not, write to 0015 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, 0016 * Boston, MA 02110-1301, USA. 0017 **/ 0018 0019 #ifdef KDE_USE_FINAL 0020 #undef Always 0021 #endif 0022 #include <list> 0023 #include <algorithm> 0024 0025 #include <qlabel.h> 0026 #include <qmenu.h> 0027 #include <qtimer.h> 0028 #include <qpushbutton.h> 0029 #include <qslider.h> 0030 #include <QFile> 0031 #include <QMetaObject> 0032 #include <QStandardPaths> 0033 0034 class KXMLGUIClient; // workaround for kde3.3 on sarge with gcc4, kactioncollection.h does not forward declare KXMLGUIClient 0035 #include <kdebug.h> 0036 #include <kconfig.h> 0037 #include <kaction.h> 0038 #include <kurlauthorized.h> 0039 #include <kiconloader.h> 0040 #include <klocalizedstring.h> 0041 #include <kparts/factory.h> 0042 #include <kstatusbar.h> 0043 0044 #include "kmplayer_part.h" 0045 #include "kmplayerview.h" 0046 #include "playlistview.h" 0047 #include "kmplayercontrolpanel.h" 0048 #include "kmplayerconfig.h" 0049 #include "kmplayerprocess.h" 0050 #include "viewarea.h" 0051 0052 #include <stdlib.h> 0053 #include <unistd.h> // unlink, getpid 0054 0055 using namespace KMPlayer; 0056 0057 typedef std::list <KMPlayerPart *> KMPlayerPartList; 0058 0059 class KMPLAYER_NO_EXPORT KMPlayerPartStatic : public GlobalShared<KMPlayerPartStatic> { 0060 public: 0061 KMPlayerPartStatic (KMPlayerPartStatic **); 0062 ~KMPlayerPartStatic (); 0063 KMPlayerPartList partlist; 0064 int counter; 0065 }; 0066 0067 static KMPlayerPartStatic * kmplayerpart_static = 0L; 0068 0069 KDE_NO_CDTOR_EXPORT 0070 KMPlayerPartStatic::KMPlayerPartStatic (KMPlayerPartStatic **glob) : GlobalShared<KMPlayerPartStatic> (glob), counter (0) { 0071 Ids::init (); 0072 } 0073 0074 KDE_NO_CDTOR_EXPORT KMPlayerPartStatic::~KMPlayerPartStatic () { 0075 kmplayerpart_static = 0L; 0076 Ids::reset (); 0077 // delete map content 0078 } 0079 0080 struct KMPLAYER_NO_EXPORT GroupPredicate { 0081 const KMPlayerPart * m_part; 0082 const QString & m_group; 0083 bool m_get_any; 0084 GroupPredicate(const KMPlayerPart *part, const QString &group, bool b=false) 0085 : m_part (part), m_group (group), m_get_any (b) {} 0086 bool operator () (const KMPlayerPart * part) const { 0087 return ((m_get_any && part != m_part && 0088 !part->master () && !part->url ().isEmpty ()) || 0089 (m_part->allowRedir (part->docBase ()) && 0090 (part->m_group == m_group || 0091 part->m_group == QString::fromLatin1("_master") || 0092 m_group == QString::fromLatin1("_master")) && 0093 (part->m_features & KMPlayerPart::Feat_Viewer) != 0094 (m_part->m_features & KMPlayerPart::Feat_Viewer))); 0095 } 0096 }; 0097 0098 //----------------------------------------------------------------------------- 0099 0100 K_EXPORT_PLUGIN(KMPlayerFactory) 0101 0102 KAboutData* KMPlayerFactory::s_about = 0L; 0103 0104 KDE_NO_CDTOR_EXPORT KMPlayerFactory::KMPlayerFactory () { 0105 } 0106 0107 KDE_NO_CDTOR_EXPORT KMPlayerFactory::~KMPlayerFactory () { 0108 } 0109 0110 KAboutData& KMPlayerFactory::aboutData() { 0111 if (!s_about) { 0112 s_about = new KAboutData("kmplayer", i18n("KMPlayer"), QStringLiteral(KMPLAYER_VERSION_STRING), 0113 i18n("Embedded MPlayer for KDE"), 0114 KAboutLicense::LGPL); 0115 s_about->addAuthor(QStringLiteral("Koos Vriezen"), QString(), "koos.vriezen@gmail.com"); 0116 } 0117 return *s_about; 0118 } 0119 0120 QObject* KMPlayerFactory::create(const char *iface, QWidget* parentWidget, QObject* parent, 0121 const QVariantList& args, const QString&) 0122 { 0123 return new KMPlayerPart(parentWidget, parent, args); 0124 } 0125 0126 //----------------------------------------------------------------------------- 0127 0128 GrabDocument::GrabDocument (KMPlayerPart *part, const QString &url, 0129 const QString &file, PlayListNotify *) 0130 : SourceDocument (part->sources () ["urlsource"], url), 0131 m_grab_file (file), 0132 m_part (part) { 0133 id = id_node_grab_document; 0134 resolved = true; 0135 } 0136 0137 void GrabDocument::activate () { 0138 media_info = new MediaInfo (this, MediaManager::AudioVideo); 0139 media_info->create (); 0140 kDebug() << src; 0141 Mrl::activate (); 0142 } 0143 0144 void GrabDocument::undefer () { 0145 begin (); 0146 } 0147 0148 void GrabDocument::begin () { 0149 setState (state_began); 0150 AudioVideoMedia *av = static_cast <AudioVideoMedia *> (media_info->media); 0151 kDebug() << m_grab_file; 0152 av->grabPicture (m_grab_file, 0); 0153 } 0154 0155 void GrabDocument::message (MessageType msg, void *content) { 0156 if (MsgMediaFinished == msg) { 0157 state = state_finished; 0158 m_part->startUrl (KUrl (), m_grab_file); 0159 // deleted here by Source::reset 0160 } else { 0161 SourceDocument::message (msg, content); 0162 } 0163 } 0164 0165 //----------------------------------------------------------------------------- 0166 0167 static bool getBoolValue (const QString & value) { 0168 return (value.toLower() != QString::fromLatin1("false") && 0169 value.toLower() != QString::fromLatin1("off") && 0170 value.toLower() != QString::fromLatin1("0")); 0171 } 0172 0173 #define SET_FEAT_ON(f) { m_features |= f; turned_off_features &= ~f; } 0174 #define SET_FEAT_OFF(f) { m_features &= ~f; turned_off_features |= f; } 0175 0176 KDE_NO_CDTOR_EXPORT KMPlayerPart::KMPlayerPart (QWidget *wparent, 0177 QObject* ppart, const QVariantList& args) 0178 : PartBase (wparent, ppart, KSharedConfig::openConfig ("kmplayerrc")), 0179 m_master (0L), 0180 m_browserextension (new KMPlayerBrowserExtension (this)), 0181 m_liveconnectextension (new KMPlayerLiveConnectExtension (this)), 0182 m_playtime_info(0), 0183 m_expected_view_width (0), 0184 m_expected_view_height (0), 0185 m_features (Feat_Unknown), 0186 m_started_emited (false), 0187 m_wait_npp_loaded (false) 0188 { 0189 setComponentData(KMPlayerFactory::aboutData()); 0190 kDebug () << "KMPlayerPart(" << this << ")::KMPlayerPart ()"; 0191 bool show_fullscreen = false; 0192 if (!kmplayerpart_static) 0193 (void) new KMPlayerPartStatic (&kmplayerpart_static); 0194 else 0195 kmplayerpart_static->ref (); 0196 setComponentData(KMPlayerFactory::aboutData ()); 0197 init (actionCollection (), 0198 QString ("/KMPlayerPart%1").arg(kmplayerpart_static->counter++), true); 0199 createBookmarkMenu (m_view->controlPanel ()->bookmarkMenu, actionCollection ()); 0200 m_view->controlPanel ()->bookmarkAction->setVisible (true); 0201 ///*KAction *playact =*/ new KAction(i18n("P&lay"), QString ("player_play"), KShortcut (), this, SLOT(play ()), actionCollection (), "play"); 0202 ///*KAction *pauseact =*/ new KAction(i18n("&Pause"), QString ("player_pause"), KShortcut (), this, SLOT(pause ()), actionCollection (), "pause"); 0203 ///*KAction *stopact =*/ new KAction(i18n("&Stop"), QString ("player_stop"), KShortcut (), this, SLOT(stop ()), actionCollection (), "stop"); 0204 //new KAction (i18n ("Increase Volume"), QString ("player_volume"), KShortcut (), this, SLOT (increaseVolume ()), actionCollection (), "edit_volume_up"); 0205 //new KAction (i18n ("Decrease Volume"), QString ("player_volume"), KShortcut (), this, SLOT (decreaseVolume ()), actionCollection (), "edit_volume_down"); 0206 Source *source = m_sources ["urlsource"]; 0207 KMPlayer::ControlPanel * panel = m_view->controlPanel (); 0208 QVariantList::const_iterator it = args.begin (); 0209 QVariantList::const_iterator end = args.end (); 0210 int turned_off_features = 0; 0211 for ( ; it != end; ++it) { 0212 QString arg = (*it).toString(); 0213 int equalPos = arg.indexOf("="); 0214 if (equalPos > 0) { 0215 QString name = arg.left(equalPos).toLower(); 0216 QString value = arg.right(arg.size() - equalPos - 1); 0217 if (value.at(0)=='\"') 0218 value = value.right (value.size () - 1); 0219 if (value.at (value.size () - 1) == '\"') 0220 value.truncate (value.size () - 1); 0221 kDebug () << "name=" << name << " value=" << value; 0222 if (name == "href") { 0223 m_href_url = value; 0224 } else if (name == QString::fromLatin1("target")) { 0225 m_target = value; 0226 } else if (name == QString::fromLatin1("width")) { 0227 m_noresize = true; 0228 m_expected_view_width = value.toInt (); 0229 } else if (name == QString::fromLatin1("height")) { 0230 m_noresize = true; 0231 m_expected_view_height = value.toInt (); 0232 } else if (name == QString::fromLatin1("controls")) { 0233 //http://service.real.com/help/library/guides/production8/realpgd.htm?src=noref,rnhmpg_080301,rnhmtn,nosrc 0234 //http://service.real.com/help/library/guides/production8/htmfiles/control.htm 0235 QStringList sl = value.split(QChar (',')); 0236 const QStringList::const_iterator e = sl.constEnd (); 0237 for (QStringList::const_iterator i = sl.constBegin (); i != e; ++i) { 0238 QString val_lower ((*i).toLower ()); 0239 if (val_lower == QString::fromLatin1("imagewindow")) { 0240 SET_FEAT_ON (Feat_ImageWindow | Feat_Viewer) 0241 } else if (val_lower == QString::fromLatin1("all")) { 0242 m_features = (Feat_Controls | Feat_StatusBar); 0243 } else if (val_lower == QString::fromLatin1("tacctrl")) { 0244 SET_FEAT_ON (Feat_Label) 0245 } else if (val_lower == QString::fromLatin1("controlpanel")) { 0246 SET_FEAT_ON (Feat_Controls) 0247 } else if (val_lower == QString::fromLatin1("infovolumepanel")){ 0248 SET_FEAT_ON (Feat_Controls) // TODO 0249 } else if (val_lower == QString::fromLatin1("positionfield") || 0250 val_lower == QString::fromLatin1("positionslider")) { 0251 setAutoControls (false); 0252 panel->positionSlider ()->show (); 0253 SET_FEAT_ON (Feat_Controls) 0254 } else if ( val_lower == QString::fromLatin1("homectrl")) { 0255 setAutoControls (false); 0256 panel->button (KMPlayer::ControlPanel::button_config)->show(); 0257 } else if (val_lower == QString::fromLatin1("mutectrl") || 0258 val_lower == QString::fromLatin1("mutevolume")) { 0259 setAutoControls (false); 0260 panel->volumeBar()->setMinimumSize (QSize (20, panel->volumeBar()->minimumSize ().height ())); 0261 panel->volumeBar()->show (); 0262 SET_FEAT_ON (Feat_Controls) 0263 } else if (val_lower == QString::fromLatin1("rwctrl")) { 0264 setAutoControls (false); 0265 panel->button (KMPlayer::ControlPanel::button_back)->show (); // rewind ? 0266 SET_FEAT_ON (Feat_Controls) 0267 } else if ( val_lower == QString::fromLatin1("ffctrl")) { 0268 setAutoControls (false); 0269 panel->button(KMPlayer::ControlPanel::button_forward)->show(); 0270 m_features = Feat_Controls; 0271 } else if ( val_lower ==QString::fromLatin1("stopbutton")) { 0272 setAutoControls (false); 0273 panel->button (KMPlayer::ControlPanel::button_stop)->show (); 0274 SET_FEAT_ON (Feat_Controls) 0275 } else if (val_lower == QString::fromLatin1("playbutton") || 0276 val_lower ==QString::fromLatin1("playonlybutton")) { 0277 setAutoControls (false); 0278 panel->button (KMPlayer::ControlPanel::button_play)->show (); 0279 SET_FEAT_ON (Feat_Controls) 0280 } else if (val_lower ==QString::fromLatin1("pausebutton")) { 0281 setAutoControls (false); 0282 panel->button (KMPlayer::ControlPanel::button_pause)->show (); 0283 SET_FEAT_ON (Feat_Controls) 0284 } else if (val_lower == QString::fromLatin1("statusbar") || 0285 val_lower == QString::fromLatin1("statusfield")) { 0286 SET_FEAT_ON (Feat_StatusBar) 0287 } else if (val_lower == QString::fromLatin1("infopanel")) { 0288 SET_FEAT_ON (Feat_InfoPanel) 0289 } else if (val_lower == QString::fromLatin1("playlist")) { 0290 SET_FEAT_ON (Feat_PlayList) 0291 } else if (val_lower==QString::fromLatin1("volumeslider")) { 0292 SET_FEAT_ON (Feat_VolumeSlider) 0293 setAutoControls (false); 0294 panel->volumeBar()->show (); 0295 panel->volumeBar()->setMinimumSize (QSize (20, panel->volumeBar()->minimumSize ().height ())); 0296 } 0297 } 0298 } else if (name == QString::fromLatin1("uimode")) { 0299 QString val_lower (value.toLower ()); 0300 if (val_lower == QString::fromLatin1("full")) 0301 SET_FEAT_ON (Feat_All & ~(Feat_PlayList | Feat_ImageWindow)) 0302 // TODO: invisible, none, mini 0303 } else if (name == QString::fromLatin1("nolabels")) { 0304 SET_FEAT_OFF (Feat_Label) 0305 } else if (name == QString::fromLatin1("nocontrols")) { 0306 SET_FEAT_OFF (Feat_Controls | Feat_VolumeSlider) 0307 } else if (name == QString::fromLatin1("showdisplay")) { 0308 // the author name, the clip name, and the copyright information 0309 if (getBoolValue (value)) 0310 SET_FEAT_ON (Feat_InfoPanel) 0311 else 0312 SET_FEAT_OFF (Feat_InfoPanel) 0313 } else if (name == QString::fromLatin1("showcontrols") || 0314 name == QString::fromLatin1("controller")) { 0315 if (getBoolValue (value)) 0316 SET_FEAT_ON (Feat_Viewer | Feat_Controls) 0317 else 0318 SET_FEAT_OFF (Feat_Controls | Feat_VolumeSlider) 0319 } else if (name == QString::fromLatin1("showstatusbar")) { 0320 if (getBoolValue (value)) 0321 SET_FEAT_ON (Feat_Viewer | Feat_StatusBar) 0322 else 0323 SET_FEAT_OFF (Feat_StatusBar) 0324 // else showcaptioning/showgotobar/showpositioncontrols/showtracker 0325 } else if (name == QString::fromLatin1("console")) { 0326 m_group = value.isEmpty() ? QString::fromLatin1("_anonymous") : value; 0327 } else if (name == QString::fromLatin1("__khtml__pluginbaseurl")) { 0328 m_docbase = KUrl (value); 0329 } else if (name == QString::fromLatin1("src")) { 0330 m_src_url = value; 0331 } else if (name == QString::fromLatin1("filename")) { 0332 m_file_name = value; 0333 } else if (name == QString::fromLatin1 ("fullscreenmode")) { 0334 show_fullscreen = getBoolValue (value); 0335 } else if (name == QString::fromLatin1 ("autostart")) { 0336 source->setAutoPlay (getBoolValue (value)); 0337 } 0338 // volume/clicktoplay/transparentatstart/animationatstart 0339 // autorewind/displaysize/border 0340 if (!name.startsWith (QString::fromLatin1 ("__khtml__"))) 0341 convertNode <KMPlayer::Element> (source->document ())->setAttribute (name, value); 0342 } 0343 } 0344 if (turned_off_features) { 0345 if (m_features == Feat_Unknown) 0346 m_features = (Feat_All & ~(Feat_PlayList | Feat_ImageWindow | Feat_StatusBar)); 0347 m_features &= ~turned_off_features; 0348 } 0349 //KParts::Part::setWidget (m_view); 0350 setXMLFile("kmplayerpartui.rc"); 0351 /*connect (panel->zoom50Action, SIGNAL (triggered (bool)), 0352 this, SLOT (setMenuZoom (bool))); 0353 panel->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom100, 0354 this, SLOT (setMenuZoom (int))); 0355 panel->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom150, 0356 this, SLOT (setMenuZoom (int)));*/ 0357 0358 m_view->setNoInfoMessages (m_features != Feat_InfoPanel); 0359 if (m_features == Feat_InfoPanel) { 0360 m_view->initDock (m_view->infoPanel ()); 0361 } else if (m_features == Feat_PlayList) { 0362 m_view->initDock (m_view->playList ()); 0363 } else if (m_features == Feat_StatusBar) { 0364 m_view->initDock (m_view->statusBar ()); 0365 } else { 0366 m_view->initDock (m_view->viewArea ()); 0367 if (m_features & Feat_StatusBar) { 0368 m_view->setStatusBarMode (KMPlayer::View::SB_Show); 0369 m_expected_view_height -= m_view->statusBar ()->height (); 0370 } 0371 if (m_features & (Feat_Controls | Feat_VolumeSlider)) { 0372 m_view->setControlPanelMode (m_features & Feat_Viewer ? KMPlayer::View::CP_Show : KMPlayer::View::CP_Only); 0373 m_expected_view_height -= m_view->controlPanel ()->height (); 0374 } else if (parent ()) 0375 m_view->setControlPanelMode (KMPlayer::View::CP_Hide); 0376 else 0377 m_view->setControlPanelMode (KMPlayer::View::CP_AutoHide); 0378 } 0379 bool group_member = !m_group.isEmpty () && m_group != QString::fromLatin1("_unique") && m_features != Feat_Unknown; 0380 if (!group_member || m_features & Feat_Viewer) { 0381 // not part of a group or we're the viewer 0382 connectPanel (m_view->controlPanel ()); 0383 if (m_features & Feat_StatusBar) { 0384 last_time_left = 0; 0385 connect (this, SIGNAL (positioned (int, int)), 0386 this, SLOT (statusPosition (int, int))); 0387 m_playtime_info = new QLabel("--:--"); 0388 m_view->statusBar()->addPermanentWidget(m_playtime_info); 0389 } 0390 } 0391 if (group_member) { 0392 KMPlayerPartList::iterator i =kmplayerpart_static->partlist.begin (); 0393 KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end (); 0394 GroupPredicate pred (this, m_group); 0395 for (i = std::find_if (i, e, pred); 0396 i != e; 0397 i = std::find_if (++i, e, pred)) { 0398 // found viewer and control part, exchange players now 0399 KMPlayerPart * vp = (m_features & Feat_Viewer) ? this : *i; 0400 KMPlayerPart * cp = (m_features & Feat_Viewer) ? *i : this; 0401 cp->connectToPart (vp); 0402 } 0403 } else 0404 m_group.truncate (0); 0405 kmplayerpart_static->partlist.push_back (this); 0406 0407 if (m_view->isFullScreen () != show_fullscreen) 0408 m_view->fullScreen (); 0409 } 0410 0411 #undef SET_FEAT_ON 0412 #undef SET_FEAT_OFF 0413 0414 KDE_NO_CDTOR_EXPORT KMPlayerPart::~KMPlayerPart () { 0415 kDebug() << "KMPlayerPart::~KMPlayerPart"; 0416 //if (!m_group.isEmpty ()) { 0417 KMPlayerPartList::iterator i = std::find (kmplayerpart_static->partlist.begin (), kmplayerpart_static->partlist.end (), this); 0418 if (i != kmplayerpart_static->partlist.end ()) 0419 kmplayerpart_static->partlist.erase (i); 0420 else 0421 kError () << "KMPlayerPart::~KMPlayerPart group lost" << endl; 0422 //} 0423 if (!m_grab_file.isEmpty ()) 0424 ::unlink (m_grab_file.toLocal8Bit ().data ()); 0425 if (m_source) 0426 m_source->deactivate (); 0427 m_config = 0L; 0428 kmplayerpart_static->unref (); 0429 } 0430 0431 KDE_NO_EXPORT void KMPlayerPart::processCreated (KMPlayer::Process *p) { 0432 #ifdef KMPLAYER_WITH_NPP 0433 if (p->objectName() == "npp") { 0434 if (m_wait_npp_loaded) 0435 connect (p, SIGNAL (loaded ()), this, SLOT (nppLoaded ())); 0436 connect (p, SIGNAL (evaluate (const QString &, bool, QString &)), 0437 m_liveconnectextension, 0438 SLOT (evaluate (const QString &, bool, QString &))); 0439 connect (m_liveconnectextension, 0440 SIGNAL (requestGet (const uint32_t, const QString &, QString *)), 0441 p, SLOT (requestGet (const uint32_t, const QString &, QString *))); 0442 connect (m_liveconnectextension, 0443 SIGNAL (requestCall (const uint32_t, const QString &, const QStringList, QString *)), 0444 p, SLOT (requestCall (const uint32_t, const QString &, const QStringList, QString *))); 0445 } 0446 #endif 0447 } 0448 0449 KDE_NO_EXPORT bool KMPlayerPart::allowRedir (const KUrl & url) const { 0450 return KUrlAuthorized::authorizeUrlAction ("redirect", m_docbase, url); 0451 } 0452 0453 KDE_NO_EXPORT void KMPlayerPart::setAutoControls (bool b) { 0454 m_auto_controls = b; 0455 m_view->controlPanel ()->setAutoControls (b); 0456 } 0457 0458 KDE_NO_EXPORT void KMPlayerPart::viewerPartDestroyed (QObject * o) { 0459 if (o == m_master) 0460 m_master = 0L; 0461 kDebug () << "KMPlayerPart(" << this << ")::viewerPartDestroyed"; 0462 const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end(); 0463 KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group)); 0464 if (i != e && *i != this) 0465 (*i)->updatePlayerMenu (m_view->controlPanel ()); 0466 } 0467 0468 KDE_NO_EXPORT void KMPlayerPart::viewerPartProcessChanged (const char *) { 0469 const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end(); 0470 KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group)); 0471 if (i != e && *i != this) 0472 (*i)->updatePlayerMenu (m_view->controlPanel ()); 0473 } 0474 0475 KDE_NO_EXPORT void KMPlayerPart::viewerPartSourceChanged(Source *o, Source *s) { 0476 kDebug () << "KMPlayerPart::source changed " << m_master; 0477 if (m_master && m_view) { 0478 connectSource (o, s); 0479 m_master->updatePlayerMenu (m_view->controlPanel ()); 0480 } 0481 } 0482 0483 KDE_NO_EXPORT bool KMPlayerPart::openUrl(const QUrl& _url) { 0484 KUrl url; 0485 KParts::OpenUrlArguments args = arguments (); 0486 Source * urlsource = m_sources ["urlsource"]; 0487 KMPlayerPartList::iterator i =kmplayerpart_static->partlist.begin (); 0488 KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end (); 0489 GroupPredicate pred (this, m_group); 0490 bool emit_started = !m_settings->clicktoplay; 0491 0492 kDebug () << "KMPlayerPart::openUrl " << _url.url() << " " << args.mimeType();; 0493 if (args.mimeType () == "application/x-shockwave-flash" || 0494 args.mimeType () == "application/futuresplash") { 0495 m_wait_npp_loaded = true; 0496 urlsource->setAvoidRedirects (true); 0497 } 0498 0499 if (m_wait_npp_loaded && (_url.isEmpty () || _url == m_docbase)) { 0500 url = KUrl ("about:empty"); 0501 m_wait_npp_loaded = emit_started = false; 0502 } else if (!m_file_name.isEmpty () && (_url.isEmpty () || _url == m_docbase)) { 0503 url = KUrl (m_docbase, m_file_name); // fix misdetected SRC attr 0504 } else if (_url != m_docbase) { 0505 url = _url; 0506 if (!m_file_name.isEmpty() && _url.url().indexOf(m_file_name) < 0) { 0507 KUrl u (m_file_name); 0508 if ((u.protocol () == QString ("mms")) || 0509 KUrl(_url).protocol ().isEmpty ()) { 0510 // see if we somehow have to merge these 0511 int p = _url.port (); 0512 if (p > 0) 0513 u.setPort (p); 0514 if (u.path ().isEmpty ()) 0515 u.setPath (QChar ('/') + _url.host ()); 0516 if (allowRedir (u)) { 0517 url = u; 0518 kDebug () << "KMPlayerPart::openUrl compose " << m_file_name << " " << _url.url() << " ->" << u.url(); 0519 } 0520 } 0521 } 0522 } else { // if url is the container document, then it's an empty URL 0523 if (m_features & Feat_Viewer) // damn, look in the group 0524 for (i = std::find_if (i, e, pred); 0525 i != e; 0526 i = std::find_if (++i, e, pred)) 0527 if (!(*i)->url ().isEmpty ()) { 0528 url = (*i)->url (); 0529 break; 0530 } 0531 } 0532 if (!m_href_url.isEmpty () && 0533 !KUrlAuthorized::authorizeUrlAction ( 0534 "redirect", url, KUrl (m_docbase, m_href_url))) 0535 m_href_url.truncate (0); 0536 if (m_href_url.isEmpty ()) 0537 setUrl (url.url ()); 0538 0539 if (url.isEmpty ()) { 0540 if (!m_master && !(m_features & Feat_Viewer)) 0541 // no master set, wait for a viewer to attach or timeout 0542 QTimer::singleShot (50, this, SLOT (waitForImageWindowTimeOut ())); 0543 return true; 0544 } 0545 m_src_url = url.url (); 0546 0547 if (!m_group.isEmpty () && !(m_features & Feat_Viewer)) { 0548 // group member, not the image window 0549 for (i = std::find_if (i, e, pred); 0550 i != e; 0551 i = std::find_if (++i, e, pred)) 0552 if ((*i)->url ().isEmpty ()) // image window created w/o url 0553 return (*i)->startUrl (_url); 0554 QTimer::singleShot (50, this, SLOT (waitForImageWindowTimeOut ())); 0555 //kError () << "Not the ImageWindow and no ImageWindow found" << endl; 0556 return true; 0557 } 0558 if (!m_view || !url.isValid ()) 0559 return false; 0560 0561 if (!args.mimeType ().isEmpty ()) 0562 urlsource->document ()->mrl ()->mimetype = args.mimeType (); 0563 0564 startUrl (url); 0565 0566 if (emit_started && urlsource->autoPlay ()) { 0567 emit started (0L); 0568 m_started_emited = true; 0569 } 0570 return true; 0571 } 0572 0573 KDE_NO_EXPORT void 0574 KMPlayerPart::openUrl(const QUrl& u, const QString& t, const QString& srv) { 0575 m_browserextension->requestOpenURL (u, t, srv); 0576 } 0577 0578 KDE_NO_EXPORT bool KMPlayerPart::openNewURL (const KUrl & url) { 0579 m_file_name.truncate (0); 0580 m_href_url.truncate (0); 0581 m_sources ["urlsource"]->setAutoPlay (true); 0582 return openUrl (url); 0583 } 0584 0585 KDE_NO_EXPORT bool KMPlayerPart::startUrl(const KUrl &uri, const QString &img) { 0586 Source * src = sources () ["urlsource"]; 0587 KUrl url (uri); 0588 kDebug() << "uri '" << uri << "' img '" << img; 0589 if (url.isEmpty ()) { 0590 url = m_src_url; 0591 } else if (m_settings->grabhref && !m_href_url.isEmpty ()) { 0592 static int counter; 0593 m_href_url = KUrl (m_docbase, m_href_url).url (); 0594 m_grab_file = QString ("%1grab-%2-%3.jpg") 0595 .arg (QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+ "kmplayer/") 0596 .arg (getpid ()) 0597 .arg (counter++); 0598 Node *n = new GrabDocument (this, url.url (), m_grab_file, src); 0599 src->setUrl (url.url ()); 0600 m_src_url = m_href_url; 0601 src->setDocument (n, n); 0602 setSource (src); 0603 if (m_source->avoidRedirects ()) 0604 m_source->activate(); 0605 return true; 0606 } 0607 if ((m_settings->clicktoplay || !m_href_url.isEmpty ()) && 0608 (m_features & Feat_Viewer || 0609 Feat_Unknown == m_features) && 0610 m_expected_view_width > 10 && 0611 m_expected_view_height > 10 && 0612 parent () && 0613 !strcmp ("KHTMLPart", parent ()->metaObject ()->className())) { 0614 QString pic (img); 0615 if (!pic.isEmpty ()) { 0616 QFile file (pic); 0617 if (!file.exists ()) { 0618 m_grab_file.truncate (0); 0619 pic.truncate (0); 0620 } else if (!file.size ()) { 0621 pic.truncate (0); 0622 } 0623 } 0624 QString img = pic.isEmpty () 0625 ? KUrl (KIconLoader::global()->iconPath ( 0626 QString::fromLatin1 ("video-x-generic"), 0627 #ifdef KMPLAYER_WITH_CAIRO 0628 -128 0629 #else 0630 -32 0631 #endif 0632 )).url () 0633 : pic; 0634 #ifdef KMPLAYER_WITH_CAIRO 0635 QString smil = QString::fromLatin1 ( 0636 "<smil><head><layout>" 0637 "<region id='reg1' left='12.5%' top='5%' right='12.5%' bottom='5%' " 0638 "background-color='#202030' showBackground='whenActive'/>" 0639 "<region id='reg2'/>" 0640 "<region id='reg3'/>" 0641 "</layout>" 0642 "<transition id='clockwipe1' dur='1' type='clockWipe'/>" 0643 "</head>" 0644 "<body>" 0645 "<a href='%1'%2>" 0646 "<img id='image1' src='%3' region='reg%4' fit='meet' " 0647 "begin='.5' dur='indefinite' transIn='clockwipe1'/>" 0648 "</a>" 0649 "<video id='video1' region='reg2' fit='meet'/>" 0650 "</body></smil>" 0651 ).arg (m_target.isEmpty () 0652 ? QString ("#video1") 0653 : m_href_url.isEmpty () ? m_src_url : m_href_url) 0654 .arg (m_target.isEmpty () 0655 ? QString () 0656 : QString (" target='%1'").arg (m_target)) 0657 .arg (img) 0658 .arg (pic.isEmpty () ? "1" : "3"); 0659 QByteArray ba = smil.toUtf8 (); 0660 QTextStream ts (&ba, QIODevice::ReadOnly); 0661 if (m_source) 0662 m_source->deactivate (); 0663 NodePtr doc = src->document (); 0664 KMPlayer::readXML (doc, ts, QString (), false); 0665 NodePtr n = doc->document ()->getElementById ("video1"); 0666 if (n) { 0667 Mrl *mrl = new GenericURL (doc, url.url ()); 0668 n->appendChild (mrl); 0669 mrl->mimetype = doc->document ()->mimetype; 0670 mrl->opener = n; 0671 mrl->setAttributes (convertNode <Element> (doc)->attributes ()); 0672 n->closed (); 0673 NodePtr im = doc->document ()->getElementById ("image1"); 0674 if (im) 0675 im->mrl ()->access_granted = true; 0676 } 0677 doc->document ()->resolved = true; 0678 if (m_source) { 0679 m_source->activate(); 0680 } else { 0681 setSource (src); 0682 if (m_source->avoidRedirects ()) 0683 m_source->activate(); 0684 } 0685 #else 0686 if (m_view->setPicture (KUrl (img).path ())) { 0687 connect (m_view, SIGNAL (pictureClicked ()), 0688 this, SLOT (pictureClicked ())); 0689 emit completed (); 0690 m_started_emited = false; 0691 } else { 0692 return PartBase::openUrl(m_href_url.isEmpty() ? url : KUrl(m_href_url)); 0693 } 0694 #endif 0695 return true; 0696 } else 0697 return PartBase::openUrl(m_href_url.isEmpty() ? url : KUrl(m_href_url)); 0698 } 0699 0700 #ifndef KMPLAYER_WITH_CAIRO 0701 KDE_NO_EXPORT void KMPlayerPart::pictureClicked () { 0702 m_view->setPicture (QString ()); 0703 PartBase::openUrl (KUrl (m_src_url)); 0704 } 0705 #endif 0706 0707 KDE_NO_EXPORT void KMPlayerPart::waitForImageWindowTimeOut () { 0708 if (!m_master) { 0709 // still no ImageWindow attached, eg. audio only 0710 const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end(); 0711 GroupPredicate pred (this, m_group); 0712 KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, pred); 0713 bool noattach = (i == e || *i == this); 0714 if (noattach) { 0715 if (!url ().isEmpty ()) { 0716 m_features |= KMPlayerPart::Feat_Viewer; //hack, become the view 0717 for (i = std::find_if (kmplayerpart_static->partlist.begin (), e, pred); i != e; i = std::find_if (++i, e, pred)) 0718 (*i)->connectToPart (this); 0719 PartBase::openUrl (url ()); 0720 } else { // see if we can attach to something out there .. 0721 i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group, true)); 0722 noattach = (i == e); 0723 } 0724 } 0725 if (!noattach) 0726 connectToPart (*i); 0727 } 0728 } 0729 0730 KDE_NO_EXPORT bool KMPlayerPart::closeUrl () { 0731 if (!m_group.isEmpty ()) { 0732 kmplayerpart_static->partlist.remove (this); 0733 m_group.truncate (0); 0734 } 0735 return PartBase::closeUrl (); 0736 } 0737 0738 KDE_NO_EXPORT void KMPlayerPart::connectToPart (KMPlayerPart * m) { 0739 m_master = m; 0740 m->connectPanel (m_view->controlPanel ()); 0741 m->updatePlayerMenu (m_view->controlPanel ()); 0742 if (m_features & Feat_PlayList) 0743 m->connectPlaylist (m_view->playList ()); 0744 if (m_features & Feat_InfoPanel) 0745 m->connectInfoPanel (m_view->infoPanel ()); 0746 connectSource (m_source, m->source ()); 0747 connect (m, SIGNAL (destroyed (QObject *)), 0748 this, SLOT (viewerPartDestroyed (QObject *))); 0749 connect (m, SIGNAL (processChanged (const char *)), 0750 this, SLOT (viewerPartProcessChanged (const char *))); 0751 connect (m, SIGNAL (sourceChanged (KMPlayer::Source *, KMPlayer::Source *)), 0752 this, SLOT (viewerPartSourceChanged (KMPlayer::Source *, KMPlayer::Source *))); 0753 if (m_features & Feat_StatusBar) { 0754 last_time_left = 0; 0755 connect (m, SIGNAL (positioned (int, int)), 0756 this, SLOT (statusPosition (int, int))); 0757 m_playtime_info = new QLabel("--:--"); 0758 m_view->statusBar()->addPermanentWidget(m_playtime_info); 0759 } 0760 } 0761 0762 KDE_NO_EXPORT void KMPlayerPart::setLoaded (int percentage) { 0763 PartBase::setLoaded (percentage); 0764 if (percentage < 100) { 0765 m_browserextension->setLoadingProgress (percentage); 0766 m_browserextension->infoMessage 0767 // xgettext: no-c-format 0768 (QString::number (percentage) + i18n ("% Cache fill")); 0769 } 0770 } 0771 0772 KDE_NO_EXPORT void KMPlayerPart::playingStarted () { 0773 const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end(); 0774 KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group)); 0775 if (i != e && *i != this && m_view && (*i)->source()) { 0776 m_view->controlPanel ()->setPlaying (true); 0777 m_view->controlPanel ()->showPositionSlider(!!(*i)->source()->length ()); 0778 m_view->controlPanel()->enableSeekButtons((*i)->source()->isSeekable()); 0779 emit loading (100); 0780 } else if (m_source) 0781 KMPlayer::PartBase::playingStarted (); 0782 else 0783 return; // ugh 0784 kDebug () << "KMPlayerPart::processStartedPlaying "; 0785 if (m_settings->sizeratio && !m_noresize && m_source->width() > 0 && m_source->height() > 0) 0786 m_liveconnectextension->setSize (m_source->width(), m_source->height()); 0787 m_browserextension->setLoadingProgress (100); 0788 if (m_started_emited && !m_wait_npp_loaded) { 0789 emit completed (); 0790 m_started_emited = false; 0791 } 0792 m_liveconnectextension->started (); 0793 m_browserextension->infoMessage (i18n("KMPlayer: Playing")); 0794 } 0795 0796 KDE_NO_EXPORT void KMPlayerPart::playingStopped () { 0797 KMPlayer::PartBase::playingStopped (); 0798 if (m_started_emited && !m_wait_npp_loaded) { 0799 m_started_emited = false; 0800 m_browserextension->setLoadingProgress (100); 0801 emit completed (); 0802 } 0803 m_liveconnectextension->finished (); 0804 m_browserextension->infoMessage (i18n ("KMPlayer: Stop Playing")); 0805 if (m_view) 0806 m_view->controlPanel ()->setPlaying (false); 0807 } 0808 0809 KDE_NO_EXPORT void KMPlayerPart::nppLoaded () { 0810 if (m_started_emited && m_wait_npp_loaded) { 0811 m_wait_npp_loaded = false; 0812 m_started_emited = false; 0813 m_browserextension->setLoadingProgress (100); 0814 emit completed (); 0815 } 0816 } 0817 0818 KDE_NO_EXPORT void KMPlayerPart::setMenuZoom (int /*id*/) { 0819 /*int w = 0, h = 0; 0820 if (m_source) 0821 m_source->dimensions (w, h); 0822 if (id == KMPlayer::ControlPanel::menu_zoom100) { 0823 m_liveconnectextension->setSize (w, h); 0824 return; 0825 } 0826 float scale = 1.5; 0827 if (id == KMPlayer::ControlPanel::menu_zoom50) 0828 scale = 0.5; 0829 if (m_view) 0830 m_liveconnectextension->setSize (int (scale * m_view->viewArea ()->width ()), 0831 int (scale * m_view->viewArea ()->height()));*/ 0832 } 0833 0834 KDE_NO_EXPORT void KMPlayerPart::statusPosition (int pos, int length) { 0835 int left = (length - pos) / 10; 0836 if (left != last_time_left) { 0837 last_time_left = left; 0838 QString text ("--:--"); 0839 if (left > 0) { 0840 int h = left / 3600; 0841 int m = (left % 3600) / 60; 0842 int s = left % 60; 0843 if (h > 0) 0844 text.sprintf ("%d:%02d:%02d", h, m, s); 0845 else 0846 text.sprintf ("%02d:%02d", m, s); 0847 } 0848 m_playtime_info->setText(text); 0849 } 0850 } 0851 0852 KDE_NO_EXPORT QString KMPlayerPart::doEvaluate (const QString &script) { 0853 return m_liveconnectextension->evaluate ( 0854 QString ("this.__kmplayer__res=" ) + script); 0855 } 0856 0857 //--------------------------------------------------------------------- 0858 0859 KDE_NO_CDTOR_EXPORT KMPlayerBrowserExtension::KMPlayerBrowserExtension (KMPlayerPart * parent) 0860 : KParts::BrowserExtension (parent) { 0861 } 0862 0863 KDE_NO_EXPORT void KMPlayerBrowserExtension::urlChanged (const QString & url) { 0864 emit setLocationBarUrl (url); 0865 } 0866 0867 KDE_NO_EXPORT void KMPlayerBrowserExtension::setLoadingProgress (int percentage) { 0868 emit loadingProgress (percentage); 0869 } 0870 0871 KDE_NO_EXPORT void KMPlayerBrowserExtension::saveState (QDataStream & stream) { 0872 stream << static_cast <PartBase *> (parent ())->url ().url (); 0873 } 0874 0875 KDE_NO_EXPORT void KMPlayerBrowserExtension::restoreState (QDataStream & stream) { 0876 QString url; 0877 stream >> url; 0878 static_cast <PartBase *> (parent ())->openUrl (KUrl(url)); 0879 } 0880 0881 KDE_NO_EXPORT void KMPlayerBrowserExtension::requestOpenURL (const KUrl & url, const QString & target, const QString & service) { 0882 KParts::OpenUrlArguments args; 0883 KParts::BrowserArguments bargs; 0884 bargs.frameName = target; 0885 args.setMimeType (service); 0886 emit openUrlRequest (url, args, bargs); 0887 } 0888 0889 //--------------------------------------------------------------------- 0890 /* 0891 * add 0892 * .error.errorCount 0893 * .error.item(count) 0894 * .errorDescription 0895 * .errorCode 0896 * .controls.stop() 0897 * .controls.play() 0898 */ 0899 0900 enum JSCommand { 0901 notsupported, 0902 canpause, canplay, canstop, canseek, 0903 isfullscreen, isloop, isaspect, showcontrolpanel, 0904 length, width, height, playstate, position, source, setsource, protocol, 0905 gotourl, nextentry, jsc_pause, play, preventry, start, stop, 0906 volume, setvolume, 0907 prop_error, prop_source, prop_volume, 0908 prop_qt_status, prop_qt_rate 0909 }; 0910 0911 struct KMPLAYER_NO_EXPORT JSCommandEntry { 0912 const char * name; 0913 JSCommand command; 0914 const char * defaultvalue; 0915 const KParts::LiveConnectExtension::Type rettype; 0916 }; 0917 0918 // keep this list in alphabetic order 0919 // http://service.real.com/help/library/guides/realonescripting/browse/htmfiles/embedmet.htm 0920 static const JSCommandEntry JSCommandList [] = { 0921 { "CanPause", canpause, 0L, KParts::LiveConnectExtension::TypeBool }, 0922 { "CanPlay", canplay, 0L, KParts::LiveConnectExtension::TypeBool }, 0923 { "CanStop", canstop, 0L, KParts::LiveConnectExtension::TypeBool }, 0924 { "DoGotoURL", notsupported, 0L, KParts::LiveConnectExtension::TypeVoid }, 0925 { "DoNextEntry", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0926 { "DoPause", jsc_pause, "true", KParts::LiveConnectExtension::TypeBool }, 0927 { "DoPlay", play, 0L, KParts::LiveConnectExtension::TypeBool }, 0928 { "DoPlayPause", play, 0L, KParts::LiveConnectExtension::TypeBool }, 0929 { "DoPrevEntry", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0930 { "DoStop", stop, 0L, KParts::LiveConnectExtension::TypeBool }, 0931 { "FileName", prop_source, 0L, KParts::LiveConnectExtension::TypeString }, 0932 { "GetAuthor", notsupported, "noname", KParts::LiveConnectExtension::TypeString }, 0933 { "GetAutoGoToURL", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 0934 { "GetBackgroundColor", notsupported, "#ffffff", KParts::LiveConnectExtension::TypeString }, 0935 { "GetBandwidthAverage", notsupported, "64", KParts::LiveConnectExtension::TypeNumber }, 0936 { "GetBandwidthCurrent", notsupported, "64", KParts::LiveConnectExtension::TypeNumber }, 0937 { "GetBufferingTimeElapsed", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0938 { "GetBufferingTimeRemaining", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0939 { "GetCanSeek", canseek, 0L, KParts::LiveConnectExtension::TypeBool }, 0940 { "GetCenter", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 0941 { "GetClipHeight", height, 0L, KParts::LiveConnectExtension::TypeNumber }, 0942 { "GetClipWidth", width, 0L, KParts::LiveConnectExtension::TypeNumber }, 0943 { "GetConnectionBandwidth", notsupported, "64", KParts::LiveConnectExtension::TypeNumber }, 0944 { "GetConsole", notsupported, "unknown", KParts::LiveConnectExtension::TypeString }, 0945 { "GetConsoleEvents", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0946 { "GetControls", notsupported, "buttons", KParts::LiveConnectExtension::TypeString }, 0947 { "GetCopyright", notsupported, "(c) whoever", KParts::LiveConnectExtension::TypeString }, 0948 { "GetCurrentEntry", notsupported, "1", KParts::LiveConnectExtension::TypeNumber }, 0949 { "GetDuration", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0950 { "GetDRMInfo", notsupported, "RNBA", KParts::LiveConnectExtension::TypeString }, 0951 { "GetDoubleSize", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0952 { "GetEntryAbstract", notsupported, "abstract", KParts::LiveConnectExtension::TypeString }, 0953 { "GetEntryAuthor", notsupported, "noname", KParts::LiveConnectExtension::TypeString }, 0954 { "GetEntryCopyright", notsupported, "(c)", KParts::LiveConnectExtension::TypeString }, 0955 { "GetEntryTitle", notsupported, "title", KParts::LiveConnectExtension::TypeString }, 0956 { "GetFullScreen", isfullscreen, 0L, KParts::LiveConnectExtension::TypeBool }, 0957 { "GetImageStatus", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0958 { "GetLastErrorMoreInfoURL", notsupported, "no error", KParts::LiveConnectExtension::TypeString }, 0959 { "GetLastErrorRMACode", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0960 { "GetLastErrorSeverity", notsupported, "6", KParts::LiveConnectExtension::TypeNumber }, 0961 { "GetLastErrorUserCode", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0962 { "GetLastErrorUserString", notsupported, "no error", KParts::LiveConnectExtension::TypeString }, 0963 { "GetLastMessage", notsupported, "no error", KParts::LiveConnectExtension::TypeString }, 0964 { "GetLastStatus", notsupported, "no error", KParts::LiveConnectExtension::TypeString }, 0965 { "GetLength", length, 0L, KParts::LiveConnectExtension::TypeNumber }, 0966 { "GetLiveState", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0967 { "GetLoop", isloop, 0L, KParts::LiveConnectExtension::TypeBool }, 0968 { "GetMaintainAspect", isaspect, 0L, KParts::LiveConnectExtension::TypeBool }, 0969 { "GetMute", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0970 { "GetNumEntries", notsupported, "1", KParts::LiveConnectExtension::TypeNumber }, 0971 { "GetNumLoop", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0972 { "GetNumSources", notsupported, "1", KParts::LiveConnectExtension::TypeNumber }, 0973 { "GetOriginalSize", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 0974 { "GetPacketsEarly", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0975 { "GetPacketsLate", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0976 { "GetPacketsMissing", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0977 { "GetPacketsOutOfOrder", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0978 { "GetPacketsReceived", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0979 { "GetPacketsTotal", notsupported, "0", KParts::LiveConnectExtension::TypeNumber }, 0980 { "GetPlayState", playstate, 0L, KParts::LiveConnectExtension::TypeNumber }, 0981 { "GetPluginStatus", prop_qt_status, NULL, KParts::LiveConnectExtension::TypeString }, 0982 { "GetPosition", position, 0L, KParts::LiveConnectExtension::TypeNumber }, 0983 { "GetPreFetch", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0984 { "GetRate", prop_qt_rate, NULL, KParts::LiveConnectExtension::TypeNumber }, 0985 { "GetShowAbout", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0986 { "GetShowPreferences", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0987 { "GetShowStatistics", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0988 { "GetShuffle", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0989 { "GetSource", source, 0L, KParts::LiveConnectExtension::TypeString }, 0990 { "GetSourceTransport", protocol, 0L, KParts::LiveConnectExtension::TypeString }, 0991 { "GetStereoState", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 0992 { "GetTitle", notsupported, "title", KParts::LiveConnectExtension::TypeString }, 0993 { "GetVersionInfo", notsupported, "version", KParts::LiveConnectExtension::TypeString }, 0994 { "GetVolume", volume, "100", KParts::LiveConnectExtension::TypeNumber }, 0995 { "GetWantErrors", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0996 { "GetWantKeyboardEvents", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0997 { "GetWantMouseEvents", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0998 { "HasNextEntry", notsupported, "false", KParts::LiveConnectExtension::TypeBool }, 0999 { "Pause", jsc_pause, 0L, KParts::LiveConnectExtension::TypeBool }, 1000 { "Play", play, 0L, KParts::LiveConnectExtension::TypeBool }, 1001 { "SetAuthor", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1002 { "SetAutoGoToURL", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1003 { "SetAutoStart", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1004 { "SetBackgroundColor", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1005 { "SetCanSeek", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1006 { "SetCenter", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1007 { "SetConsole", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1008 { "SetConsoleEvents", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1009 { "SetControls", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1010 { "SetCopyright", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1011 { "SetCurrentPosition", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1012 { "SetDoubleSize", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1013 { "SetFileName", setsource, 0L, KParts::LiveConnectExtension::TypeBool }, 1014 { "SetFullScreen", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1015 { "SetImageStatus", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1016 { "SetLoop", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1017 { "SetMaintainAspect", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1018 { "SetMute", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1019 { "SetNumLoop", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1020 { "SetOriginalSize", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1021 { "SetPosition", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1022 { "SetPreFetch", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1023 { "SetShowAbout", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1024 { "SetShowPreferences", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1025 { "SetShowStatistics", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1026 { "SetShuffle", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1027 { "SetSource", setsource, 0L, KParts::LiveConnectExtension::TypeBool }, 1028 { "SetTitle", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1029 { "SetVolume", setvolume, "true", KParts::LiveConnectExtension::TypeBool }, 1030 { "SetWantErrors", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1031 { "SetWantKeyboardEvents", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1032 { "SetWantMouseEvents", notsupported, "true", KParts::LiveConnectExtension::TypeBool }, 1033 { "ShowControls", showcontrolpanel, "true", KParts::LiveConnectExtension::TypeBool }, 1034 { "Start", start, 0L, KParts::LiveConnectExtension::TypeBool }, 1035 { "Stop", stop, 0L, KParts::LiveConnectExtension::TypeBool }, 1036 { "Volume", prop_volume, "100", KParts::LiveConnectExtension::TypeNumber }, 1037 { "errorCode", prop_error, "0",KParts::LiveConnectExtension::TypeNumber }, 1038 { "pause", jsc_pause, 0L, KParts::LiveConnectExtension::TypeBool }, 1039 { "play", play, 0L, KParts::LiveConnectExtension::TypeBool }, 1040 { "put", prop_source, 0L, KParts::LiveConnectExtension::TypeString }, 1041 { "stop", stop, 0L, KParts::LiveConnectExtension::TypeBool }, 1042 { "volume", volume, 0L, KParts::LiveConnectExtension::TypeBool }, 1043 }; 1044 1045 static const JSCommandEntry * getJSCommandEntry (const char * name, int start = 0, int end = sizeof (JSCommandList)/sizeof (JSCommandEntry)) { 1046 if (end - start < 2) { 1047 if (start != end && !strcasecmp (JSCommandList[start].name, name)) 1048 return &JSCommandList[start]; 1049 return 0L; 1050 } 1051 int mid = (start + end) / 2; 1052 int cmp = strcasecmp (JSCommandList[mid].name, name); 1053 if (cmp < 0) 1054 return getJSCommandEntry (name, mid + 1, end); 1055 if (cmp > 0) 1056 return getJSCommandEntry (name, start, mid); 1057 return &JSCommandList[mid]; 1058 } 1059 1060 KDE_NO_CDTOR_EXPORT KMPlayerLiveConnectExtension::KMPlayerLiveConnectExtension (KMPlayerPart * parent) 1061 : KParts::LiveConnectExtension (parent), player (parent), 1062 lastJSCommandEntry (0L), 1063 object_counter (0), 1064 m_started (false), 1065 m_enablefinish (false), 1066 m_evaluating (false), 1067 m_skip_put (false) { 1068 connect (parent, SIGNAL (started (KIO::Job *)), this, SLOT (started ())); 1069 } 1070 1071 KDE_NO_CDTOR_EXPORT KMPlayerLiveConnectExtension::~KMPlayerLiveConnectExtension() { 1072 kDebug () << "KMPlayerLiveConnectExtension::~KMPlayerLiveConnectExtension()"; 1073 } 1074 1075 KDE_NO_EXPORT void KMPlayerLiveConnectExtension::started () { 1076 m_started = true; 1077 } 1078 1079 KDE_NO_EXPORT void KMPlayerLiveConnectExtension::finished () { 1080 if (m_started && m_enablefinish) { 1081 KParts::LiveConnectExtension::ArgList args; 1082 args.push_back (qMakePair (KParts::LiveConnectExtension::TypeString, QString("if (window.onFinished) onFinished();"))); 1083 emit partEvent (0, "eval", args); 1084 m_started = true; 1085 m_enablefinish = false; 1086 } 1087 } 1088 1089 KDE_NO_EXPORT 1090 QString KMPlayerLiveConnectExtension::evaluate (const QString &script) { 1091 KParts::LiveConnectExtension::ArgList args; 1092 args.push_back(qMakePair(KParts::LiveConnectExtension::TypeString, script)); 1093 script_result.clear (); 1094 emit partEvent (0, "eval", args); 1095 //kDebug() << script << script_result; 1096 return script_result; 1097 } 1098 1099 KDE_NO_EXPORT void KMPlayerLiveConnectExtension::evaluate ( 1100 const QString & scr, bool store, QString & result) { 1101 m_evaluating = true; 1102 1103 QString script (scr); 1104 script = script.replace ('\\', "\\\\"); 1105 script = script.replace ('\n', "\\n"); 1106 script = script.replace ('\r', ""); 1107 script = script.replace ('"', "\\\""); 1108 QString obj_var = QString ("this.__kmplayer__obj_%1").arg (object_counter); 1109 script = obj_var + QString ("=eval(\"%1\")").arg (script); 1110 QString eval_result = evaluate (script); 1111 1112 bool clear_result = true; 1113 if (!store) { 1114 result = eval_result; 1115 if (scr.startsWith ("this.__kmplayer__obj_")) { 1116 // TODO add dbus method for this 1117 int p = scr.indexOf ("=null", 21); 1118 if (p > -1) { 1119 int i = scr.mid (21, p - 21).toInt (); 1120 if (i == (int)object_counter-1) 1121 object_counter--; // works most of the time :-) 1122 } 1123 } 1124 } else { 1125 script = QString ("this.__kmplayer__res=typeof(%1)").arg (obj_var); 1126 QString result_type = evaluate (script); 1127 1128 if (result_type == "string") { 1129 result = QString ("s:") + eval_result; 1130 } else if (result_type == "object" || 1131 result_type == "function" || 1132 result_type.startsWith ("[")) { 1133 result = QString ("o:") + obj_var; 1134 clear_result = false; 1135 object_counter++; 1136 } else if (result_type == "number") { 1137 result = QString ("n:") + eval_result; 1138 } else if (result_type == "boolean") { 1139 result = QString ("b:") + eval_result; 1140 } else if (result_type == "undefined" || result_type == "null") { 1141 result = QString ("u:") + eval_result; 1142 } else { 1143 result = "error"; 1144 } 1145 } 1146 if (clear_result) 1147 evaluate (obj_var + "=null"); 1148 1149 script_result.clear (); 1150 1151 m_evaluating = false; 1152 } 1153 1154 static 1155 bool str2LC (const QString s, KParts::LiveConnectExtension::Type &type, QString &rval) { 1156 if (s == "error") 1157 return false; 1158 if (s == "o:function") { 1159 type = KParts::LiveConnectExtension::TypeFunction; 1160 } else if (s.startsWith (QChar ('\'')) && s.endsWith (QChar ('\''))) { 1161 type = KParts::LiveConnectExtension::TypeString; 1162 rval = s.mid (1, s.size () - 2); 1163 } else if (s == "true" || s == "false") { 1164 type = KParts::LiveConnectExtension::TypeBool; 1165 rval = s; 1166 } else { 1167 bool ok; 1168 s.toInt (&ok); 1169 if (!ok) 1170 s.toDouble (&ok); 1171 if (ok) { 1172 type = KParts::LiveConnectExtension::TypeNumber; 1173 rval = s; 1174 } else { 1175 type = KParts::LiveConnectExtension::TypeVoid; 1176 rval = s; 1177 } 1178 } 1179 return true; 1180 } 1181 1182 KDE_NO_EXPORT bool KMPlayerLiveConnectExtension::get 1183 (const unsigned long id, const QString & name, 1184 KParts::LiveConnectExtension::Type & type, 1185 unsigned long & rid, QString & rval) 1186 { 1187 if (name.startsWith ("__kmplayer__obj_")) { 1188 if (m_evaluating) 1189 return false; 1190 rid = 0; 1191 type = KParts::LiveConnectExtension::TypeString; 1192 rval = "Access denied"; 1193 return true; 1194 } 1195 if (name.startsWith ("__kmplayer_func")) { 1196 rid = id; 1197 type = KParts::LiveConnectExtension::TypeFunction; 1198 return true; 1199 } 1200 if (name.startsWith ("__kmplayer_util_") || 1201 redir_funcs.indexOf(name) >= 0) 1202 return false; 1203 if (name == "__kmplayer_unique_name") { 1204 rval = QString ("__kmplayer__obj_%1").arg (object_counter); 1205 type = KParts::LiveConnectExtension::TypeString; 1206 rid = id; 1207 object_counter++; 1208 m_allow = rval; 1209 return true; 1210 } 1211 rid = id; 1212 QString req_result; 1213 emit requestGet (id, name, &req_result); 1214 if (!req_result.isEmpty ()) { 1215 if (str2LC (req_result, type, rval)) { 1216 if (KParts::LiveConnectExtension::TypeFunction == type) { 1217 m_skip_put = true; 1218 if (!redir_funcs.size ()) 1219 evaluate ( 1220 "this.__kmplayer_util_make_arg = function(arg) {" 1221 " var t = typeof arg;" 1222 " if (t == 'number')" 1223 " return 'n:' + arg;" 1224 " if (t == 'object') {" 1225 " var s = this.__kmplayer_unique_name;" 1226 " this[s] = arg;" 1227 " return 'o:this.' + s;" 1228 " }" 1229 " if (t == 'function') {" 1230 " var s = this.__kmplayer_unique_name;" 1231 " this[s] = arg;" 1232 " return 'o:this.' + s;" 1233 " }" 1234 " if (t == 'boolean')" 1235 " return 'b:' + arg;" 1236 " if (t == 'undefined' || t == null)" 1237 " return 'u:' + arg;" 1238 " var s = '' + arg;" 1239 " s = s.replace('\\\\', '\\\\\\\\');" 1240 " s = s.replace('\\n', '\\\\n');" 1241 " return 's:' + s;" 1242 "}"); 1243 evaluate (QString ( 1244 "this.%1=function(){" 1245 " var args=[];" 1246 " for (var i=0;i<arguments.length;++i)" 1247 " args.push (this.__kmplayer_util_make_arg(" 1248 " arguments[i]));" 1249 " return this.__kmplayer_func('%2',args.join('\\n'));" 1250 "}") 1251 .arg (name) 1252 .arg (name)); 1253 redir_funcs.push_back (name); 1254 m_skip_put = false; 1255 return false; 1256 } 1257 return true; 1258 } 1259 } 1260 kDebug () << "[01;35mget[00m " << name; 1261 const JSCommandEntry * entry = getJSCommandEntry (name.toAscii ().constData ()); 1262 if (!entry) 1263 return false; 1264 type = entry->rettype; 1265 switch (entry->command) { 1266 case prop_source: 1267 type = KParts::LiveConnectExtension::TypeString; 1268 rval = player->url ().url (); 1269 break; 1270 case prop_volume: 1271 if (player->view ()) 1272 rval = QString::number (player->viewWidget ()->controlPanel()->volumeBar()->value()); 1273 break; 1274 case prop_error: 1275 type = KParts::LiveConnectExtension::TypeNumber; 1276 rval = QString::number (0); 1277 break; 1278 case prop_qt_status: 1279 rval = player->getStatus (); 1280 break; 1281 case prop_qt_rate: 1282 rval = QString::number (0.0); 1283 if (player->source() && player->source()->document() && 1284 player->source()->document()->state != 1285 KMPlayer::Node::state_deferred && 1286 player->source()->document()->unfinished ()) 1287 rval = QString::number (1.0); 1288 break; 1289 default: 1290 lastJSCommandEntry = entry; 1291 type = KParts::LiveConnectExtension::TypeFunction; 1292 } 1293 return true; 1294 } 1295 1296 KDE_NO_EXPORT bool KMPlayerLiveConnectExtension::put 1297 (const unsigned long, const QString & name, const QString & val) { 1298 if (m_skip_put) 1299 return false; 1300 if (name == "__kmplayer__res") { 1301 script_result = val; 1302 return true; 1303 } 1304 if (name.startsWith ("__kmplayer__obj_")) { 1305 script_result = val; 1306 if (name == m_allow) { 1307 m_allow.clear (); 1308 return false; 1309 } 1310 return !m_evaluating; 1311 } 1312 1313 kDebug () << "[01;35mput[00m " << name << "=" << val; 1314 1315 const JSCommandEntry * entry = getJSCommandEntry (name.toAscii ().constData ()); 1316 if (!entry) 1317 return false; 1318 switch (entry->command) { 1319 case prop_source: { 1320 KUrl url (val); 1321 if (player->allowRedir (url)) 1322 player->openNewURL (url); 1323 break; 1324 } 1325 case prop_volume: 1326 if (player->view ()) 1327 player->viewWidget ()->controlPanel()->volumeBar()->setValue(val.toInt ()); 1328 break; 1329 default: 1330 return false; 1331 } 1332 return true; 1333 } 1334 1335 static QString unescapeArg (const QString &arg) { 1336 QString s; 1337 bool last_escape = false; 1338 for (int i = 0; i < arg.length (); ++i) 1339 switch (arg[i].unicode ()) { 1340 case '\\': 1341 if (last_escape) { 1342 s += QChar ('\\'); 1343 last_escape = false; 1344 } else { 1345 last_escape = true; 1346 } 1347 break; 1348 case 'n': 1349 if (last_escape) { 1350 s += QChar ('\n'); 1351 last_escape = false; 1352 break; 1353 } // else fall through 1354 default: 1355 if (last_escape) { 1356 kError() << "unescape error " << arg; 1357 last_escape = false; 1358 } 1359 s += arg[i]; 1360 } 1361 return s; 1362 } 1363 1364 KDE_NO_EXPORT bool KMPlayerLiveConnectExtension::call 1365 (const unsigned long id, const QString & name, 1366 const QStringList & args, KParts::LiveConnectExtension::Type & type, 1367 unsigned long & rid, QString & rval) { 1368 QString func = name; 1369 QString req_result; 1370 QStringList arglst; 1371 int oid = id; 1372 QList<QString>::const_iterator it = args.begin (); 1373 if (func == "__kmplayer_func") { 1374 if ( it != args.end ()) { 1375 func = *it; 1376 oid = 0; 1377 if ( ++it != args.end ()) { 1378 QStringList a = (*it).split ("\n"); 1379 for (QStringList::iterator i = a.begin(); i != a.end (); ++i) 1380 arglst << ((*i).startsWith ("s:") ? unescapeArg (*i) : *i); 1381 } 1382 } else { 1383 return false; 1384 } 1385 } else { 1386 for (; it != args.end (); ++it) { 1387 bool ok; 1388 int iv = (*it).toInt (&ok); 1389 if (ok) { 1390 arglst << QString ("n:%1").arg (iv); 1391 } else { 1392 double dv = (*it).toDouble (&ok); 1393 if (ok) { 1394 arglst << QString ("n:%1").arg (dv); 1395 } else { 1396 arglst << QString ("s:%1").arg (*it); 1397 } 1398 } 1399 } 1400 } 1401 rid = oid; 1402 emit requestCall (oid, func, arglst, &req_result); 1403 if (!req_result.isEmpty ()) { 1404 if (str2LC (req_result, type, rval)) 1405 return true; 1406 } 1407 kDebug () << "[01;35mentry[00m " << func; 1408 const JSCommandEntry * entry = lastJSCommandEntry; 1409 const QByteArray ascii = func.toAscii (); 1410 if (!entry || strcmp (entry->name, ascii.constData ())) 1411 entry = getJSCommandEntry (ascii.constData ()); 1412 if (!entry) 1413 return false; 1414 for (QStringList::size_type i = 0; i < args.size (); ++i) 1415 kDebug () << " " << args[i]; 1416 if (!player->view ()) 1417 return false; 1418 type = entry->rettype; 1419 switch (entry->command) { 1420 case notsupported: 1421 if (entry->rettype != KParts::LiveConnectExtension::TypeVoid) 1422 rval = entry->defaultvalue; 1423 break; 1424 case canpause: 1425 rval = (player->playing () && !player->viewWidget ()->controlPanel()->button (KMPlayer::ControlPanel::button_pause)->isChecked ()) ? "true" : "false"; 1426 break; 1427 case canplay: 1428 rval = (!player->playing () || player->viewWidget ()->controlPanel()->button (KMPlayer::ControlPanel::button_pause)->isChecked ()) ? "true" : "false"; 1429 break; 1430 case canstop: 1431 rval = player->playing () ? "true" : "false"; 1432 break; 1433 case canseek: 1434 rval = player->source ()->isSeekable () ? "true" : "false"; 1435 break; 1436 case play: 1437 if (args.size ()) { 1438 KUrl url (args.first ()); 1439 if (player->allowRedir (url)) 1440 player->openNewURL (url); 1441 } else 1442 player->play (); 1443 rval = "true"; 1444 break; 1445 case start: 1446 player->play (); 1447 rval = "true"; 1448 break; 1449 case stop: 1450 player->stop (); 1451 rval = "true"; 1452 break; 1453 case showcontrolpanel: 1454 if (args.size () && 1455 (args.first () == QString::fromLatin1 ("0") || 1456 args.first () == QString::fromLatin1 ("false"))) 1457 player->viewWidget ()->setControlPanelMode (KMPlayer::View::CP_Hide); 1458 else 1459 player->viewWidget ()->setControlPanelMode (KMPlayer::View::CP_Show); 1460 break; 1461 case jsc_pause: 1462 player->pause (); 1463 rval = "true"; 1464 break; 1465 case isloop: 1466 rval = player->settings ()->loop ? "true" : "false"; 1467 break; 1468 case isaspect: 1469 rval = player->settings ()->sizeratio ? "true" : "false"; 1470 break; 1471 case isfullscreen: 1472 rval = player->viewWidget ()->isFullScreen () ? "true" : "false"; 1473 break; 1474 case length: 1475 rval.setNum (player->source ()->length ()); 1476 break; 1477 case width: 1478 rval.setNum (player->source ()->width ()); 1479 break; 1480 case height: 1481 rval.setNum (player->source ()->height ()); 1482 break; 1483 case playstate: // FIXME 0-6 1484 rval = player->playing () ? "3" : "0"; 1485 break; 1486 case position: 1487 rval.setNum (player->position ()); 1488 break; 1489 case protocol: 1490 rval = player->url ().protocol (); 1491 break; 1492 case setsource: 1493 rval ="false"; 1494 if (args.size ()) { 1495 KUrl url (args.first ()); 1496 if (player->allowRedir (url) && player->openNewURL (url)) 1497 rval = "true"; 1498 } 1499 break; 1500 case setvolume: 1501 if (!args.size ()) 1502 return false; 1503 player->viewWidget ()->controlPanel()->volumeBar()->setValue(args.first ().toInt ()); 1504 rval = "true"; 1505 break; 1506 case source: 1507 rval = player->url ().url (); 1508 break; 1509 case volume: 1510 if (player->view ()) 1511 rval = QString::number (player->viewWidget ()->controlPanel()->volumeBar()->value()); 1512 break; 1513 default: 1514 return false; 1515 } 1516 return true; 1517 } 1518 1519 KDE_NO_EXPORT void KMPlayerLiveConnectExtension::unregister (const unsigned long) { 1520 } 1521 1522 KDE_NO_EXPORT void KMPlayerLiveConnectExtension::setSize (int w, int h) { 1523 KMPlayer::View * view = static_cast <KMPlayer::View*> (player->view ()); 1524 if (view->controlPanelMode () == KMPlayer::View::CP_Show) 1525 h += view->controlPanel()->height(); 1526 QString jscode; 1527 jscode.sprintf("try { eval(\"this.setAttribute('WIDTH',%d);this.setAttribute('HEIGHT',%d)\"); } catch(e){}", w, h); 1528 KParts::LiveConnectExtension::ArgList args; 1529 args.push_back (qMakePair (KParts::LiveConnectExtension::TypeString, jscode)); 1530 emit partEvent (0, "eval", args); 1531 } 1532 1533 #include "kmplayer_part.moc"