KMPlayer – media player
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1208 lines
54KB

  1. /**
  2. * Copyright (C) 2002-2003 by Koos Vriezen <koos.vriezen@gmail.com>
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License version 2 as published by the Free Software Foundation.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Library General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Library General Public License
  14. * along with this library; see the file COPYING.LIB. If not, write to
  15. * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  16. * Boston, MA 02110-1301, USA.
  17. **/
  18. #ifdef KDE_USE_FINAL
  19. #undef Always
  20. #endif
  21. #include <list>
  22. #include <algorithm>
  23. #include <config.h>
  24. #include <tqpopupmenu.h>
  25. #include <tqtimer.h>
  26. #include <tqpushbutton.h>
  27. #include <tqslider.h>
  28. class KXMLGUIClient; // workaround for trinity.3 on sarge with gcc4, tdeactioncollection.h does not forward declare KXMLGUIClient
  29. #include <klibloader.h>
  30. #include <kdebug.h>
  31. #include <tdeconfig.h>
  32. #include <ksimpleconfig.h>
  33. #include <tdeaction.h>
  34. #include <tdeapplication.h>
  35. #include <tdelocale.h>
  36. #include <kinstance.h>
  37. #include <tdeparts/factory.h>
  38. #include <kstaticdeleter.h>
  39. #include <kstatusbar.h>
  40. #include "kmplayer_part.h"
  41. #include "kmplayerview.h"
  42. #include "viewarea.h"
  43. #include "kmplayercontrolpanel.h"
  44. #include "kmplayerconfig.h"
  45. #include "kmplayerprocess.h"
  46. using namespace KMPlayer;
  47. typedef std::list <KMPlayerPart *> KMPlayerPartList;
  48. struct KMPLAYER_NO_EXPORT KMPlayerPartStatic {
  49. KMPlayerPartStatic ();
  50. ~KMPlayerPartStatic ();
  51. KMPlayerPartList partlist;
  52. };
  53. static KMPlayerPartStatic * kmplayerpart_static = 0L;
  54. KDE_NO_CDTOR_EXPORT KMPlayerPartStatic::KMPlayerPartStatic () {
  55. StringPool::init ();
  56. }
  57. KDE_NO_CDTOR_EXPORT KMPlayerPartStatic::~KMPlayerPartStatic () {
  58. kmplayerpart_static = 0L;
  59. StringPool::reset ();
  60. // delete map content
  61. }
  62. struct KMPLAYER_NO_EXPORT GroupPredicate {
  63. const KMPlayerPart * m_part;
  64. const TQString & m_group;
  65. bool m_get_any;
  66. GroupPredicate(const KMPlayerPart *part, const TQString &group, bool b=false)
  67. : m_part (part), m_group (group), m_get_any (b) {}
  68. bool operator () (const KMPlayerPart * part) const {
  69. return ((m_get_any && part != m_part &&
  70. !part->master () && !part->url ().isEmpty ()) ||
  71. (m_part->allowRedir (part->m_docbase) &&
  72. (part->m_group == m_group ||
  73. part->m_group == TQString::fromLatin1("_master") ||
  74. m_group == TQString::fromLatin1("_master")) &&
  75. (part->m_features & KMPlayerPart::Feat_Viewer) !=
  76. (m_part->m_features & KMPlayerPart::Feat_Viewer)));
  77. }
  78. };
  79. static KStaticDeleter <KMPlayerPartStatic> kmplayerpart_staticdeleter;
  80. //-----------------------------------------------------------------------------
  81. class KMPlayerFactory : public KParts::Factory {
  82. public:
  83. KMPlayerFactory ();
  84. virtual ~KMPlayerFactory ();
  85. virtual KParts::Part *createPartObject
  86. (TQWidget *wparent, const char *wname,
  87. TQObject *parent, const char *name,
  88. const char *className, const TQStringList &args);
  89. static TDEInstance * instance () { return s_instance; }
  90. private:
  91. static TDEInstance * s_instance;
  92. };
  93. K_EXPORT_COMPONENT_FACTORY (libkmplayerpart, KMPlayerFactory)
  94. TDEInstance *KMPlayerFactory::s_instance = 0;
  95. KDE_NO_CDTOR_EXPORT KMPlayerFactory::KMPlayerFactory () {
  96. s_instance = new TDEInstance ("kmplayer");
  97. }
  98. KDE_NO_CDTOR_EXPORT KMPlayerFactory::~KMPlayerFactory () {
  99. delete s_instance;
  100. }
  101. KDE_NO_EXPORT KParts::Part *KMPlayerFactory::createPartObject
  102. (TQWidget *wparent, const char *wname,
  103. TQObject *parent, const char * name,
  104. const char * cls, const TQStringList & args) {
  105. kdDebug() << "KMPlayerFactory::createPartObject " << cls << endl;
  106. return new KMPlayerPart (wparent, wname, parent, name, args);
  107. }
  108. //-----------------------------------------------------------------------------
  109. static bool getBoolValue (const TQString & value) {
  110. return (value.lower() != TQString::fromLatin1("false") &&
  111. value.lower() != TQString::fromLatin1("off") &&
  112. value.lower() != TQString::fromLatin1("0"));
  113. }
  114. #define SET_FEAT_ON(f) { m_features |= f; turned_off_features &= ~f; }
  115. #define SET_FEAT_OFF(f) { m_features &= ~f; turned_off_features |= f; }
  116. KDE_NO_CDTOR_EXPORT KMPlayerPart::KMPlayerPart (TQWidget * wparent, const char *wname,
  117. TQObject * parent, const char *name, const TQStringList &args)
  118. : PartBase (wparent, wname, parent, name, new TDEConfig ("kmplayerrc")),
  119. m_master (0L),
  120. m_browserextension (new KMPlayerBrowserExtension (this)),
  121. m_liveconnectextension (new KMPlayerLiveConnectExtension (this)),
  122. m_features (Feat_Unknown),
  123. m_started_emited (false),
  124. m_havehref (false) {
  125. kdDebug () << "KMPlayerPart(" << this << ")::KMPlayerPart ()" << endl;
  126. bool show_fullscreen = false;
  127. if (!kmplayerpart_static)
  128. kmplayerpart_static = kmplayerpart_staticdeleter.setObject (new KMPlayerPartStatic ());
  129. setInstance (KMPlayerFactory::instance (), true);
  130. init (actionCollection ());
  131. m_sources ["hrefsource"] = (new KMPlayerHRefSource (this));
  132. #ifdef HAVE_NSPR
  133. KMPlayer::NpPlayer *npp = (KMPlayer::NpPlayer *) players () ["npp"];
  134. connect (npp, TQT_SIGNAL (evaluate (const TQString &, TQString &)),
  135. m_liveconnectextension, TQT_SLOT (evaluate (const TQString &, TQString &)));
  136. connect (npp, TQT_SIGNAL (openUrl (const KURL &, const TQString &)),
  137. m_browserextension,
  138. TQT_SLOT (slotRequestOpenURL (const KURL &, const TQString &)));
  139. #endif
  140. /*TDEAction *playact =*/ new TDEAction(i18n("P&lay"), TQString ("media-playback-start"), TDEShortcut (), this, TQT_SLOT(play ()), actionCollection (), "play");
  141. /*TDEAction *pauseact =*/ new TDEAction(i18n("&Pause"), TQString ("media-playback-pause"), TDEShortcut (), this, TQT_SLOT(pause ()), actionCollection (), "pause");
  142. /*TDEAction *stopact =*/ new TDEAction(i18n("&Stop"), TQString ("media-playback-stop"), TDEShortcut (), this, TQT_SLOT(stop ()), actionCollection (), "stop");
  143. new TDEAction (i18n ("Increase Volume"), TQString ("player_volume"), TDEShortcut (), this, TQT_SLOT (increaseVolume ()), actionCollection (), "edit_volume_up");
  144. new TDEAction (i18n ("Decrease Volume"), TQString ("player_volume"), TDEShortcut (), this, TQT_SLOT (decreaseVolume ()), actionCollection (), "edit_volume_down");
  145. Source * urlsource = m_sources ["urlsource"];
  146. KMPlayer::ControlPanel * panel = m_view->controlPanel ();
  147. TQStringList::const_iterator it = args.begin ();
  148. TQStringList::const_iterator end = args.end ();
  149. int turned_off_features = 0;
  150. for ( ; it != end; ++it) {
  151. int equalPos = (*it).find("=");
  152. if (equalPos > 0) {
  153. TQString name = (*it).left (equalPos).lower ();
  154. TQString value = (*it).right ((*it).length () - equalPos - 1);
  155. if (value.at(0)=='\"')
  156. value = value.right (value.length () - 1);
  157. if (value.at (value.length () - 1) == '\"')
  158. value.truncate (value.length () - 1);
  159. kdDebug () << "name=" << name << " value=" << value << endl;
  160. if (name == "href") {
  161. urlsource->setURL (KURL (value));
  162. urlsource->setIdentified (false);
  163. m_havehref = true;
  164. } else if (name == TQString::fromLatin1("width")) {
  165. m_noresize = true;
  166. } else if (name == TQString::fromLatin1("height")) {
  167. m_noresize = true;
  168. } else if (name == TQString::fromLatin1("type")) {
  169. urlsource->document ()->mrl ()->mimetype = value;
  170. } else if (name == TQString::fromLatin1("controls")) {
  171. //http://service.real.com/help/library/guides/production8/realpgd.htm?src=noref,rnhmpg_080301,rnhmtn,nosrc
  172. //http://service.real.com/help/library/guides/production8/htmfiles/control.htm
  173. TQStringList sl = TQStringList::split (TQChar (','), value);
  174. TQStringList::const_iterator it = sl.begin ();
  175. const TQStringList::const_iterator e = sl.end ();
  176. for (TQStringList::const_iterator i = sl.begin (); i != e; ++i) {
  177. TQString val_lower ((*i).lower ());
  178. if (val_lower == TQString::fromLatin1("imagewindow")) {
  179. SET_FEAT_ON (Feat_ImageWindow | Feat_Viewer)
  180. } else if (val_lower == TQString::fromLatin1("all")) {
  181. m_features = (Feat_Controls | Feat_StatusBar);
  182. } else if (val_lower == TQString::fromLatin1("tacctrl")) {
  183. SET_FEAT_ON (Feat_Label)
  184. } else if (val_lower == TQString::fromLatin1("controlpanel")) {
  185. SET_FEAT_ON (Feat_Controls)
  186. } else if (val_lower == TQString::fromLatin1("infovolumepanel")){
  187. SET_FEAT_ON (Feat_Controls) // TODO
  188. } else if (val_lower == TQString::fromLatin1("positionfield") ||
  189. val_lower == TQString::fromLatin1("positionslider")) {
  190. setAutoControls (false);
  191. panel->positionSlider ()->show ();
  192. SET_FEAT_ON (Feat_Controls)
  193. } else if ( val_lower == TQString::fromLatin1("homectrl")) {
  194. setAutoControls (false);
  195. panel->button (KMPlayer::ControlPanel::button_config)->show();
  196. } else if (val_lower == TQString::fromLatin1("mutectrl") ||
  197. val_lower == TQString::fromLatin1("mutevolume")) {
  198. setAutoControls (false);
  199. panel->volumeBar()->setMinimumSize (TQSize (20, panel->volumeBar()->minimumSize ().height ()));
  200. panel->volumeBar()->show ();
  201. SET_FEAT_ON (Feat_Controls)
  202. } else if (val_lower == TQString::fromLatin1("rwctrl")) {
  203. setAutoControls (false);
  204. panel->button (KMPlayer::ControlPanel::button_back)->show (); // rewind ?
  205. SET_FEAT_ON (Feat_Controls)
  206. } else if ( val_lower == TQString::fromLatin1("ffctrl")) {
  207. setAutoControls (false);
  208. panel->button(KMPlayer::ControlPanel::button_forward)->show();
  209. m_features = Feat_Controls;
  210. } else if ( val_lower ==TQString::fromLatin1("stopbutton")) {
  211. setAutoControls (false);
  212. panel->button (KMPlayer::ControlPanel::button_stop)->show ();
  213. SET_FEAT_ON (Feat_Controls)
  214. } else if (val_lower == TQString::fromLatin1("playbutton") ||
  215. val_lower ==TQString::fromLatin1("playonlybutton")) {
  216. setAutoControls (false);
  217. panel->button (KMPlayer::ControlPanel::button_play)->show ();
  218. SET_FEAT_ON (Feat_Controls)
  219. } else if (val_lower ==TQString::fromLatin1("pausebutton")) {
  220. setAutoControls (false);
  221. panel->button (KMPlayer::ControlPanel::button_pause)->show ();
  222. SET_FEAT_ON (Feat_Controls)
  223. } else if (val_lower == TQString::fromLatin1("statusbar") ||
  224. val_lower == TQString::fromLatin1("statusfield")) {
  225. SET_FEAT_ON (Feat_StatusBar)
  226. } else if (val_lower == TQString::fromLatin1("infopanel")) {
  227. SET_FEAT_ON (Feat_InfoPanel)
  228. } else if (val_lower == TQString::fromLatin1("playlist")) {
  229. SET_FEAT_ON (Feat_PlayList)
  230. } else if (val_lower==TQString::fromLatin1("volumeslider")) {
  231. SET_FEAT_ON (Feat_VolumeSlider)
  232. setAutoControls (false);
  233. panel->volumeBar()->show ();
  234. panel->volumeBar()->setMinimumSize (TQSize (20, panel->volumeBar()->minimumSize ().height ()));
  235. }
  236. }
  237. } else if (name == TQString::fromLatin1("uimode")) {
  238. TQString val_lower (value.lower ());
  239. if (val_lower == TQString::fromLatin1("full"))
  240. SET_FEAT_ON (Feat_All & ~(Feat_PlayList | Feat_ImageWindow))
  241. // TODO: invisible, none, mini
  242. } else if (name == TQString::fromLatin1("nolabels")) {
  243. SET_FEAT_OFF (Feat_Label)
  244. } else if (name == TQString::fromLatin1("nocontrols")) {
  245. SET_FEAT_OFF (Feat_Controls | Feat_VolumeSlider)
  246. } else if (name == TQString::fromLatin1("showdisplay")) {
  247. // the author name, the clip name, and the copyright information
  248. if (getBoolValue (value))
  249. SET_FEAT_ON (Feat_InfoPanel)
  250. else
  251. SET_FEAT_OFF (Feat_InfoPanel)
  252. } else if (name == TQString::fromLatin1("showcontrols")) {
  253. if (getBoolValue (value))
  254. SET_FEAT_ON (Feat_Viewer | Feat_Controls)
  255. else
  256. SET_FEAT_OFF (Feat_Controls | Feat_VolumeSlider)
  257. } else if (name == TQString::fromLatin1("showstatusbar")) {
  258. if (getBoolValue (value))
  259. SET_FEAT_ON (Feat_Viewer | Feat_StatusBar)
  260. else
  261. SET_FEAT_OFF (Feat_StatusBar)
  262. // else showcaptioning/showgotobar/showpositioncontrols/showtracker
  263. } else if (name == TQString::fromLatin1("console")) {
  264. m_group = value.isEmpty() ? TQString::fromLatin1("_anonymous") : value;
  265. } else if (name == TQString::fromLatin1("__tdehtml__pluginbaseurl")) {
  266. m_docbase = KURL (value);
  267. } else if (name == TQString::fromLatin1("src")) {
  268. m_src_url = value;
  269. } else if (name == TQString::fromLatin1("filename")) {
  270. m_file_name = value;
  271. } else if (name == TQString::fromLatin1 ("fullscreenmode")) {
  272. show_fullscreen = getBoolValue (value);
  273. } else if (name == TQString::fromLatin1 ("autostart")) {
  274. urlsource->setAutoPlay (getBoolValue (value));
  275. }
  276. // volume/clicktoplay/transparentatstart/animationatstart
  277. // autorewind/displaysize/border
  278. if (name.startsWith (TQString::fromLatin1 ("__tdehtml__")))
  279. name = name.mid (9);
  280. convertNode <KMPlayer::Element> (urlsource->document ())->setAttribute (name, value);
  281. }
  282. }
  283. if (turned_off_features) {
  284. if (m_features == Feat_Unknown)
  285. m_features = (Feat_All & ~(Feat_PlayList | Feat_ImageWindow));
  286. m_features &= ~turned_off_features;
  287. }
  288. //KParts::Part::setWidget (m_view);
  289. setXMLFile("kmplayerpartui.rc");
  290. panel->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom50,
  291. this, TQT_SLOT (setMenuZoom (int)));
  292. panel->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom100,
  293. this, TQT_SLOT (setMenuZoom (int)));
  294. panel->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom150,
  295. this, TQT_SLOT (setMenuZoom (int)));
  296. panel->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom200,
  297. this, TQT_SLOT (setMenuZoom (int)));
  298. panel->zoomMenu ()->connectItem (KMPlayer::ControlPanel::menu_zoom300,
  299. this, TQT_SLOT (setMenuZoom (int)));
  300. m_view->setNoInfoMessages (m_features != Feat_InfoPanel);
  301. if (m_features == Feat_InfoPanel)
  302. m_view->setInfoPanelOnly ();
  303. else if (m_features == Feat_PlayList)
  304. m_view->setPlaylistOnly ();
  305. else {
  306. if (m_features & Feat_StatusBar)
  307. m_view->setStatusBarMode (KMPlayer::View::SB_Show);
  308. if (m_features & (Feat_Controls | Feat_VolumeSlider))
  309. m_view->setControlPanelMode (m_features & Feat_Viewer ? KMPlayer::View::CP_Show : KMPlayer::View::CP_Only);
  310. else if (m_features & Feat_ImageWindow)
  311. m_view->setControlPanelMode (KMPlayer::View::CP_Hide);
  312. else
  313. m_view->setControlPanelMode (KMPlayer::View::CP_AutoHide);
  314. }
  315. bool group_member = !m_group.isEmpty () && m_group != TQString::fromLatin1("_unique") && m_features != Feat_Unknown;
  316. if (!group_member || m_features & Feat_Viewer) {
  317. // not part of a group or we're the viewer
  318. setProcess ("mplayer");
  319. setRecorder ("mencoder");
  320. connectPanel (m_view->controlPanel ());
  321. if (m_features & Feat_StatusBar) {
  322. last_time_left = 0;
  323. connect (this, TQT_SIGNAL (positioned (int, int)),
  324. this, TQT_SLOT (statusPosition (int, int)));
  325. m_view->statusBar ()->insertItem (TQString ("--:--"), 1, 0, true);
  326. }
  327. }
  328. if (group_member) {
  329. KMPlayerPartList::iterator i =kmplayerpart_static->partlist.begin ();
  330. KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end ();
  331. GroupPredicate pred (this, m_group);
  332. for (i = std::find_if (i, e, pred);
  333. i != e;
  334. i = std::find_if (++i, e, pred)) {
  335. // found viewer and control part, exchange players now
  336. KMPlayerPart * vp = (m_features & Feat_Viewer) ? this : *i;
  337. KMPlayerPart * cp = (m_features & Feat_Viewer) ? *i : this;
  338. setProcess ("mplayer");
  339. cp->connectToPart (vp);
  340. }
  341. } else
  342. m_group.truncate (0);
  343. kmplayerpart_static->partlist.push_back (this);
  344. TQWidget *pwidget = view ()->parentWidget ();
  345. if (pwidget) {
  346. m_view->viewArea()->setPaletteBackgroundColor(pwidget->paletteBackgroundColor ());
  347. m_view->viewer()->setBackgroundColor(pwidget->paletteBackgroundColor());
  348. }
  349. if (m_view->isFullScreen () != show_fullscreen)
  350. m_view->fullScreen ();
  351. }
  352. #undef SET_FEAT_ON
  353. #undef SET_FEAT_OFF
  354. KDE_NO_CDTOR_EXPORT KMPlayerPart::~KMPlayerPart () {
  355. kdDebug() << "KMPlayerPart::~KMPlayerPart" << endl;
  356. //if (!m_group.isEmpty ()) {
  357. KMPlayerPartList::iterator i = std::find (kmplayerpart_static->partlist.begin (), kmplayerpart_static->partlist.end (), this);
  358. if (i != kmplayerpart_static->partlist.end ())
  359. kmplayerpart_static->partlist.erase (i);
  360. else
  361. kdError () << "KMPlayerPart::~KMPlayerPart group lost" << endl;
  362. //}
  363. delete m_config;
  364. m_config = 0L;
  365. }
  366. KDE_NO_EXPORT bool KMPlayerPart::allowRedir (const KURL & url) const {
  367. return kapp->authorizeURLAction ("redirect", m_docbase, url);
  368. }
  369. KDE_NO_EXPORT void KMPlayerPart::setAutoControls (bool b) {
  370. m_auto_controls = b;
  371. m_view->controlPanel ()->setAutoControls (b);
  372. }
  373. KDE_NO_EXPORT void KMPlayerPart::viewerPartDestroyed (TQObject * o) {
  374. if (o == m_master)
  375. m_master = 0L;
  376. kdDebug () << "KMPlayerPart(" << this << ")::viewerPartDestroyed" << endl;
  377. const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end();
  378. KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group));
  379. if (i != e && *i != this)
  380. (*i)->updatePlayerMenu (m_view->controlPanel ());
  381. }
  382. KDE_NO_EXPORT void KMPlayerPart::viewerPartProcessChanged (const char *) {
  383. const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end();
  384. KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group));
  385. if (i != e && *i != this)
  386. (*i)->updatePlayerMenu (m_view->controlPanel ());
  387. }
  388. KDE_NO_EXPORT void KMPlayerPart::viewerPartSourceChanged(Source *o, Source *s) {
  389. kdDebug () << "KMPlayerPart::source changed " << m_master << endl;
  390. if (m_master && m_view) {
  391. connectSource (o, s);
  392. m_master->updatePlayerMenu (m_view->controlPanel ());
  393. }
  394. }
  395. KDE_NO_EXPORT bool KMPlayerPart::openURL (const KURL & _url) {
  396. kdDebug () << "KMPlayerPart::openURL " << _url.url() << endl;
  397. Source * urlsource = m_sources ["urlsource"];
  398. KMPlayerHRefSource * hrefsource = static_cast <KMPlayerHRefSource *>(m_sources ["hrefsource"]);
  399. KMPlayerPartList::iterator i =kmplayerpart_static->partlist.begin ();
  400. KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end ();
  401. GroupPredicate pred (this, m_group);
  402. KURL url;
  403. if (!m_file_name.isEmpty () && (_url.isEmpty () || _url == m_docbase))
  404. url = KURL (m_docbase, m_file_name); // fix misdetected SRC attr
  405. else if (_url != m_docbase) {
  406. url = _url;
  407. if (!m_file_name.isEmpty () && _url.url ().find (m_file_name) < 0) {
  408. KURL u (m_file_name);
  409. if ((u.protocol () == TQString ("mms")) ||
  410. _url.protocol ().isEmpty ()) {
  411. // see if we somehow have to merge these
  412. int p = _url.port ();
  413. if (p > 0)
  414. u.setPort (p);
  415. if (u.path ().isEmpty ())
  416. u.setPath (TQChar ('/') + _url.host ());
  417. if (allowRedir (u)) {
  418. url = u;
  419. kdDebug () << "KMPlayerPart::openURL compose " << m_file_name << " " << _url.url() << " ->" << u.url() << endl;
  420. }
  421. }
  422. }
  423. } else { // if url is the container document, then it's an empty URL
  424. if (m_features & Feat_Viewer) // damn, look in the group
  425. for (i = std::find_if (i, e, pred);
  426. i != e;
  427. i = std::find_if (++i, e, pred))
  428. if (!(*i)->url ().isEmpty ()) {
  429. url = (*i)->url ();
  430. break;
  431. }
  432. }
  433. if (m_havehref && (!kapp->authorizeURLAction ("redirect", url, urlsource->url ()) || !m_settings->allowhref)) {
  434. m_havehref = false;
  435. url = urlsource->url ();
  436. }
  437. if (!m_havehref)
  438. setURL (url);
  439. if (url.isEmpty ()) {
  440. if (!m_master && !(m_features & Feat_Viewer))
  441. // no master set, wait for a viewer to attach or timeout
  442. TQTimer::singleShot (50, this, TQT_SLOT (waitForImageWindowTimeOut ()));
  443. return true;
  444. }
  445. if (!m_group.isEmpty () && !(m_features & Feat_Viewer)) {
  446. // group member, not the image window
  447. for (i = std::find_if (i, e, pred);
  448. i != e;
  449. i = std::find_if (++i, e, pred))
  450. if ((*i)->url ().isEmpty ()) // image window created w/o url
  451. return (*i)->openURL (_url);
  452. TQTimer::singleShot (50, this, TQT_SLOT (waitForImageWindowTimeOut ()));
  453. //kdError () << "Not the ImageWindow and no ImageWindow found" << endl;
  454. return true;
  455. }
  456. if (!m_view || !url.isValid ()) return false;
  457. KParts::URLArgs args = m_browserextension->urlArgs();
  458. if (!args.serviceType.isEmpty ())
  459. urlsource->document ()->mrl ()->mimetype = args.serviceType;
  460. if (m_havehref && m_settings->allowhref) {
  461. hrefsource->setURL (url);
  462. setSource (hrefsource);
  463. } else {
  464. hrefsource->clear ();
  465. PartBase::openURL (m_havehref ? urlsource->url () : url);
  466. if (urlsource->autoPlay ()) {
  467. emit started (0L);
  468. m_started_emited = true;
  469. }
  470. m_havehref = false;
  471. }
  472. return true;
  473. }
  474. KDE_NO_EXPORT bool KMPlayerPart::openNewURL (const KURL & url) {
  475. m_file_name.truncate (0);
  476. m_havehref = false;
  477. m_sources ["urlsource"]->setAutoPlay (true);
  478. return openURL (url);
  479. }
  480. KDE_NO_EXPORT void KMPlayerPart::waitForImageWindowTimeOut () {
  481. if (!m_master) {
  482. // still no ImageWindow attached, eg. audio only
  483. const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end();
  484. GroupPredicate pred (this, m_group);
  485. KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, pred);
  486. bool noattach = (i == e || *i == this);
  487. if (noattach) {
  488. if (!url ().isEmpty ()) {
  489. m_features |= KMPlayerPart::Feat_Viewer; //hack, become the view
  490. for (i = std::find_if (kmplayerpart_static->partlist.begin (), e, pred); i != e; i = std::find_if (++i, e, pred))
  491. (*i)->connectToPart (this);
  492. PartBase::openURL (url ());
  493. } else { // see if we can attach to something out there ..
  494. i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group, true));
  495. noattach = (i == e);
  496. }
  497. }
  498. if (!noattach)
  499. connectToPart (*i);
  500. }
  501. }
  502. KDE_NO_EXPORT bool KMPlayerPart::closeURL () {
  503. if (!m_group.isEmpty ()) {
  504. kmplayerpart_static->partlist.remove (this);
  505. m_group.truncate (0);
  506. }
  507. return PartBase::closeURL ();
  508. }
  509. KDE_NO_EXPORT void KMPlayerPart::connectToPart (KMPlayerPart * m) {
  510. m_master = m;
  511. m->connectPanel (m_view->controlPanel ());
  512. m->updatePlayerMenu (m_view->controlPanel ());
  513. if (m_features & Feat_PlayList)
  514. m->connectPlaylist (m_view->playList ());
  515. if (m_features & Feat_InfoPanel)
  516. m->connectInfoPanel (m_view->infoPanel ());
  517. connectSource (m_source, m->source ());
  518. connect (m, TQT_SIGNAL (destroyed (TQObject *)),
  519. this, TQT_SLOT (viewerPartDestroyed (TQObject *)));
  520. connect (m, TQT_SIGNAL (processChanged (const char *)),
  521. this, TQT_SLOT (viewerPartProcessChanged (const char *)));
  522. connect (m, TQT_SIGNAL (sourceChanged (KMPlayer::Source *, KMPlayer::Source *)),
  523. this, TQT_SLOT (viewerPartSourceChanged (KMPlayer::Source *, KMPlayer::Source *)));
  524. if (m_features & Feat_StatusBar) {
  525. last_time_left = 0;
  526. connect (m, TQT_SIGNAL (positioned (int, int)),
  527. this, TQT_SLOT (statusPosition (int, int)));
  528. m_view->statusBar ()->insertItem (TQString ("--:--"), 1, 0, true);
  529. }
  530. }
  531. KDE_NO_EXPORT void KMPlayerPart::setLoaded (int percentage) {
  532. PartBase::setLoaded (percentage);
  533. if (percentage < 100) {
  534. m_browserextension->setLoadingProgress (percentage);
  535. m_browserextension->infoMessage
  536. (TQString::number (percentage) + i18n ("% Cache fill"));
  537. }
  538. }
  539. KDE_NO_EXPORT void KMPlayerPart::playingStarted () {
  540. const KMPlayerPartList::iterator e =kmplayerpart_static->partlist.end();
  541. KMPlayerPartList::iterator i = std::find_if (kmplayerpart_static->partlist.begin (), e, GroupPredicate (this, m_group));
  542. if (i != e && *i != this && m_view && (*i)->source()) {
  543. m_view->controlPanel ()->setPlaying (true);
  544. m_view->controlPanel ()->showPositionSlider(!!(*i)->source()->length());
  545. m_view->controlPanel()->enableSeekButtons((*i)->source()->isSeekable());
  546. emit loading (100);
  547. } else if (m_source)
  548. KMPlayer::PartBase::playingStarted ();
  549. else
  550. return; // ugh
  551. kdDebug () << "KMPlayerPart::processStartedPlaying " << endl;
  552. if (m_settings->sizeratio && !m_noresize && m_source->width() > 0 && m_source->height() > 0)
  553. m_liveconnectextension->setSize (m_source->width(), m_source->height());
  554. m_browserextension->setLoadingProgress (100);
  555. if (m_started_emited) {
  556. emit completed ();
  557. m_started_emited = false;
  558. }
  559. m_liveconnectextension->started ();
  560. m_browserextension->infoMessage (i18n("KMPlayer: Playing"));
  561. }
  562. KDE_NO_EXPORT void KMPlayerPart::playingStopped () {
  563. KMPlayer::PartBase::playingStopped ();
  564. if (m_started_emited) {
  565. m_started_emited = false;
  566. m_browserextension->setLoadingProgress (100);
  567. emit completed ();
  568. }
  569. m_liveconnectextension->finished ();
  570. if (m_havehref)
  571. static_cast <KMPlayerHRefSource *>(m_sources["hrefsource"])->finished();
  572. m_browserextension->infoMessage (i18n ("KMPlayer: Stop Playing"));
  573. if (m_view)
  574. m_view->controlPanel ()->setPlaying (false);
  575. }
  576. KDE_NO_EXPORT void KMPlayerPart::setMenuZoom (int id) {
  577. int w = 0, h = 0;
  578. if (m_source)
  579. m_source->dimensions (w, h);
  580. if (id == KMPlayer::ControlPanel::menu_zoom100) {
  581. m_liveconnectextension->setSize (w, h);
  582. return;
  583. }
  584. float scale = 1;
  585. if (id == KMPlayer::ControlPanel::menu_zoom300)
  586. scale = 3.0;
  587. if (id == KMPlayer::ControlPanel::menu_zoom200)
  588. scale = 2.0;
  589. if (id == KMPlayer::ControlPanel::menu_zoom150)
  590. scale = 1.5;
  591. if (id == KMPlayer::ControlPanel::menu_zoom50)
  592. scale = 0.5;
  593. if (m_view->viewer ())
  594. m_liveconnectextension->setSize (int (scale * m_view->viewer ()->width ()),
  595. int (scale * m_view->viewer ()->height()));
  596. }
  597. KDE_NO_EXPORT void KMPlayerPart::statusPosition (int pos, int length) {
  598. int left = (length - pos) / 10;
  599. if (left != last_time_left) {
  600. last_time_left = left;
  601. TQString text ("--:--");
  602. if (left > 0) {
  603. int h = left / 3600;
  604. int m = (left % 3600) / 60;
  605. int s = left % 60;
  606. if (h > 0)
  607. text.sprintf ("%d:%02d:%02d", h, m, s);
  608. else
  609. text.sprintf ("%02d:%02d", m, s);
  610. }
  611. m_view->statusBar ()->changeItem (text, 1);
  612. }
  613. }
  614. //---------------------------------------------------------------------
  615. KDE_NO_CDTOR_EXPORT KMPlayerBrowserExtension::KMPlayerBrowserExtension (KMPlayerPart * parent)
  616. : KParts::BrowserExtension (parent, "KMPlayer Browser Extension") {
  617. }
  618. KDE_NO_EXPORT void KMPlayerBrowserExtension::urlChanged (const TQString & url) {
  619. emit setLocationBarURL (url);
  620. }
  621. KDE_NO_EXPORT void KMPlayerBrowserExtension::setLoadingProgress (int percentage) {
  622. emit loadingProgress (percentage);
  623. }
  624. KDE_NO_EXPORT void KMPlayerBrowserExtension::saveState (TQDataStream & stream) {
  625. stream << static_cast <PartBase *> (parent ())->url ().url ();
  626. }
  627. KDE_NO_EXPORT void KMPlayerBrowserExtension::restoreState (TQDataStream & stream) {
  628. TQString url;
  629. stream >> url;
  630. static_cast <PartBase *> (parent ())->openURL (KURL(url));
  631. }
  632. KDE_NO_EXPORT void KMPlayerBrowserExtension::requestOpenURL (const KURL & url, const TQString & target, const TQString & service) {
  633. KParts::URLArgs args;
  634. args.frameName = target;
  635. args.serviceType = service;
  636. emit openURLRequest (url, args);
  637. }
  638. KDE_NO_EXPORT void KMPlayerBrowserExtension::slotRequestOpenURL (const KURL &url, const TQString &target) {
  639. requestOpenURL (url, target, TQString ());
  640. }
  641. //---------------------------------------------------------------------
  642. /*
  643. * add
  644. * .error.errorCount
  645. * .error.item(count)
  646. * .errorDescription
  647. * .errorCode
  648. * .controls.stop()
  649. * .controls.play()
  650. */
  651. enum JSCommand {
  652. notsupported,
  653. canpause, canplay, canstop, canseek,
  654. isfullscreen, isloop, isaspect, showcontrolpanel,
  655. length, width, height, playstate, position, source, setsource, protocol,
  656. gotourl, nextentry, jsc_pause, play, preventry, start, stop,
  657. volume, setvolume,
  658. prop_error, prop_source, prop_volume
  659. };
  660. struct KMPLAYER_NO_EXPORT JSCommandEntry {
  661. const char * name;
  662. JSCommand command;
  663. const char * defaultvalue;
  664. const KParts::LiveConnectExtension::Type rettype;
  665. };
  666. // keep this list in alphabetic order
  667. // http://service.real.com/help/library/guides/realonescripting/browse/htmfiles/embedmet.htm
  668. static const JSCommandEntry JSCommandList [] = {
  669. { "CanPause", canpause, 0L, KParts::LiveConnectExtension::TypeBool },
  670. { "CanPlay", canplay, 0L, KParts::LiveConnectExtension::TypeBool },
  671. { "CanStop", canstop, 0L, KParts::LiveConnectExtension::TypeBool },
  672. { "DoGotoURL", notsupported, 0L, KParts::LiveConnectExtension::TypeVoid },
  673. { "DoNextEntry", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  674. { "DoPause", jsc_pause, "true", KParts::LiveConnectExtension::TypeBool },
  675. { "DoPlay", play, 0L, KParts::LiveConnectExtension::TypeBool },
  676. { "DoPlayPause", play, 0L, KParts::LiveConnectExtension::TypeBool },
  677. { "DoPrevEntry", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  678. { "DoStop", stop, 0L, KParts::LiveConnectExtension::TypeBool },
  679. { "FileName", prop_source, 0L, KParts::LiveConnectExtension::TypeString },
  680. { "GetAuthor", notsupported, "noname", KParts::LiveConnectExtension::TypeString },
  681. { "GetAutoGoToURL", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  682. { "GetBackgroundColor", notsupported, "#ffffff", KParts::LiveConnectExtension::TypeString },
  683. { "GetBandwidthAverage", notsupported, "64", KParts::LiveConnectExtension::TypeNumber },
  684. { "GetBandwidthCurrent", notsupported, "64", KParts::LiveConnectExtension::TypeNumber },
  685. { "GetBufferingTimeElapsed", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  686. { "GetBufferingTimeRemaining", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  687. { "GetCanSeek", canseek, 0L, KParts::LiveConnectExtension::TypeBool },
  688. { "GetCenter", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  689. { "GetClipHeight", height, 0L, KParts::LiveConnectExtension::TypeNumber },
  690. { "GetClipWidth", width, 0L, KParts::LiveConnectExtension::TypeNumber },
  691. { "GetConnectionBandwidth", notsupported, "64", KParts::LiveConnectExtension::TypeNumber },
  692. { "GetConsole", notsupported, "unknown", KParts::LiveConnectExtension::TypeString },
  693. { "GetConsoleEvents", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  694. { "GetControls", notsupported, "buttons", KParts::LiveConnectExtension::TypeString },
  695. { "GetCopyright", notsupported, "(c) whoever", KParts::LiveConnectExtension::TypeString },
  696. { "GetCurrentEntry", notsupported, "1", KParts::LiveConnectExtension::TypeNumber },
  697. { "GetDRMInfo", notsupported, "RNBA", KParts::LiveConnectExtension::TypeString },
  698. { "GetDoubleSize", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  699. { "GetEntryAbstract", notsupported, "abstract", KParts::LiveConnectExtension::TypeString },
  700. { "GetEntryAuthor", notsupported, "noname", KParts::LiveConnectExtension::TypeString },
  701. { "GetEntryCopyright", notsupported, "(c)", KParts::LiveConnectExtension::TypeString },
  702. { "GetEntryTitle", notsupported, "title", KParts::LiveConnectExtension::TypeString },
  703. { "GetFullScreen", isfullscreen, 0L, KParts::LiveConnectExtension::TypeBool },
  704. { "GetImageStatus", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  705. { "GetLastErrorMoreInfoURL", notsupported, "no error", KParts::LiveConnectExtension::TypeString },
  706. { "GetLastErrorRMACode", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  707. { "GetLastErrorSeverity", notsupported, "6", KParts::LiveConnectExtension::TypeNumber },
  708. { "GetLastErrorUserCode", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  709. { "GetLastErrorUserString", notsupported, "no error", KParts::LiveConnectExtension::TypeString },
  710. { "GetLastMessage", notsupported, "no error", KParts::LiveConnectExtension::TypeString },
  711. { "GetLastStatus", notsupported, "no error", KParts::LiveConnectExtension::TypeString },
  712. { "GetLength", length, 0L, KParts::LiveConnectExtension::TypeNumber },
  713. { "GetLiveState", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  714. { "GetLoop", isloop, 0L, KParts::LiveConnectExtension::TypeBool },
  715. { "GetMaintainAspect", isaspect, 0L, KParts::LiveConnectExtension::TypeBool },
  716. { "GetMute", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  717. { "GetNumEntries", notsupported, "1", KParts::LiveConnectExtension::TypeNumber },
  718. { "GetNumLoop", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  719. { "GetNumSources", notsupported, "1", KParts::LiveConnectExtension::TypeNumber },
  720. { "GetOriginalSize", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  721. { "GetPacketsEarly", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  722. { "GetPacketsLate", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  723. { "GetPacketsMissing", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  724. { "GetPacketsOutOfOrder", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  725. { "GetPacketsReceived", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  726. { "GetPacketsTotal", notsupported, "0", KParts::LiveConnectExtension::TypeNumber },
  727. { "GetPlayState", playstate, 0L, KParts::LiveConnectExtension::TypeNumber },
  728. { "GetPosition", position, 0L, KParts::LiveConnectExtension::TypeNumber },
  729. { "GetPreFetch", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  730. { "GetShowAbout", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  731. { "GetShowPreferences", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  732. { "GetShowStatistics", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  733. { "GetShuffle", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  734. { "GetSource", source, 0L, KParts::LiveConnectExtension::TypeString },
  735. { "GetSourceTransport", protocol, 0L, KParts::LiveConnectExtension::TypeString },
  736. { "GetStereoState", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  737. { "GetTitle", notsupported, "title", KParts::LiveConnectExtension::TypeString },
  738. { "GetVersionInfo", notsupported, "version", KParts::LiveConnectExtension::TypeString },
  739. { "GetVolume", volume, "100", KParts::LiveConnectExtension::TypeNumber },
  740. { "GetWantErrors", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  741. { "GetWantKeyboardEvents", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  742. { "GetWantMouseEvents", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  743. { "HasNextEntry", notsupported, "false", KParts::LiveConnectExtension::TypeBool },
  744. { "Pause", jsc_pause, 0L, KParts::LiveConnectExtension::TypeBool },
  745. { "Play", play, 0L, KParts::LiveConnectExtension::TypeBool },
  746. { "SetAuthor", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  747. { "SetAutoGoToURL", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  748. { "SetAutoStart", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  749. { "SetBackgroundColor", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  750. { "SetCanSeek", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  751. { "SetCenter", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  752. { "SetConsole", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  753. { "SetConsoleEvents", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  754. { "SetControls", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  755. { "SetCopyright", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  756. { "SetCurrentPosition", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  757. { "SetDoubleSize", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  758. { "SetFileName", setsource, 0L, KParts::LiveConnectExtension::TypeBool },
  759. { "SetFullScreen", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  760. { "SetImageStatus", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  761. { "SetLoop", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  762. { "SetMaintainAspect", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  763. { "SetMute", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  764. { "SetNumLoop", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  765. { "SetOriginalSize", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  766. { "SetPosition", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  767. { "SetPreFetch", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  768. { "SetShowAbout", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  769. { "SetShowPreferences", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  770. { "SetShowStatistics", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  771. { "SetShuffle", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  772. { "SetSource", setsource, 0L, KParts::LiveConnectExtension::TypeBool },
  773. { "SetTitle", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  774. { "SetVolume", setvolume, "true", KParts::LiveConnectExtension::TypeBool },
  775. { "SetWantErrors", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  776. { "SetWantKeyboardEvents", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  777. { "SetWantMouseEvents", notsupported, "true", KParts::LiveConnectExtension::TypeBool },
  778. { "ShowControls", showcontrolpanel, "true", KParts::LiveConnectExtension::TypeBool },
  779. { "Start", start, 0L, KParts::LiveConnectExtension::TypeBool },
  780. { "Stop", stop, 0L, KParts::LiveConnectExtension::TypeBool },
  781. { "Volume", prop_volume, "100", KParts::LiveConnectExtension::TypeNumber },
  782. { "errorCode", prop_error, "0",KParts::LiveConnectExtension::TypeNumber },
  783. { "pause", jsc_pause, 0L, KParts::LiveConnectExtension::TypeBool },
  784. { "play", play, 0L, KParts::LiveConnectExtension::TypeBool },
  785. { "put", prop_source, 0L, KParts::LiveConnectExtension::TypeString },
  786. { "stop", stop, 0L, KParts::LiveConnectExtension::TypeBool },
  787. { "volume", volume, 0L, KParts::LiveConnectExtension::TypeBool },
  788. };
  789. static const JSCommandEntry * getJSCommandEntry (const char * name, int start = 0, int end = sizeof (JSCommandList)/sizeof (JSCommandEntry)) {
  790. if (end - start < 2) {
  791. if (start != end && !strcasecmp (JSCommandList[start].name, name))
  792. return &JSCommandList[start];
  793. return 0L;
  794. }
  795. int mid = (start + end) / 2;
  796. int cmp = strcasecmp (JSCommandList[mid].name, name);
  797. if (cmp < 0)
  798. return getJSCommandEntry (name, mid + 1, end);
  799. if (cmp > 0)
  800. return getJSCommandEntry (name, start, mid);
  801. return &JSCommandList[mid];
  802. }
  803. KDE_NO_CDTOR_EXPORT KMPlayerLiveConnectExtension::KMPlayerLiveConnectExtension (KMPlayerPart * parent)
  804. : KParts::LiveConnectExtension (parent), player (parent),
  805. lastJSCommandEntry (0L),
  806. m_started (false),
  807. m_enablefinish (false),
  808. m_evaluating (false) {
  809. connect (parent, TQT_SIGNAL (started (TDEIO::Job *)), this, TQT_SLOT (started ()));
  810. }
  811. KDE_NO_CDTOR_EXPORT KMPlayerLiveConnectExtension::~KMPlayerLiveConnectExtension() {
  812. kdDebug () << "KMPlayerLiveConnectExtension::~KMPlayerLiveConnectExtension()" << endl;
  813. }
  814. KDE_NO_EXPORT void KMPlayerLiveConnectExtension::started () {
  815. m_started = true;
  816. }
  817. KDE_NO_EXPORT void KMPlayerLiveConnectExtension::finished () {
  818. if (m_started && m_enablefinish) {
  819. KParts::LiveConnectExtension::ArgList args;
  820. args.push_back (qMakePair (KParts::LiveConnectExtension::TypeString, TQString("if (window.onFinished) onFinished();")));
  821. emit partEvent (0, "eval", args);
  822. m_started = true;
  823. m_enablefinish = false;
  824. }
  825. }
  826. KDE_NO_EXPORT void KMPlayerLiveConnectExtension::evaluate (
  827. const TQString & scr, TQString & result) {
  828. TQString script (scr);
  829. KParts::LiveConnectExtension::ArgList args;
  830. script = script.replace ('\\', "\\\\");
  831. script = script.replace ('\n', "\\n");
  832. script = script.replace ('\r', "");
  833. script = script.replace ('"', "\\\"");
  834. script = TQString ("this.__kmplayer__res=eval(\"%1\")").arg (script);
  835. args.push_back(qMakePair(KParts::LiveConnectExtension::TypeString, script));
  836. script_result = "undefined";
  837. m_evaluating = true;
  838. emit partEvent (0, "eval", args);
  839. m_evaluating = false;
  840. result = script_result;
  841. }
  842. KDE_NO_EXPORT bool KMPlayerLiveConnectExtension::get
  843. (const unsigned long id, const TQString & name,
  844. KParts::LiveConnectExtension::Type & type,
  845. unsigned long & rid, TQString & rval)
  846. {
  847. if (name.startsWith ("__kmplayer__obj_")) {
  848. if (m_evaluating)
  849. return false;
  850. rid = 0;
  851. type = KParts::LiveConnectExtension::TypeString;
  852. rval = "Access denied";
  853. return true;
  854. }
  855. const char * str = name.ascii ();
  856. kdDebug () << "get " << str << endl;
  857. const JSCommandEntry * entry = getJSCommandEntry (str);
  858. if (!entry)
  859. return false;
  860. rid = id;
  861. type = entry->rettype;
  862. switch (entry->command) {
  863. case prop_source:
  864. type = KParts::LiveConnectExtension::TypeString;
  865. rval = player->url ().url ();
  866. break;
  867. case prop_volume:
  868. if (player->view ())
  869. rval = TQString::number (player->process()->viewer ()->view()->controlPanel()->volumeBar()->value());
  870. break;
  871. case prop_error:
  872. type = KParts::LiveConnectExtension::TypeNumber;
  873. rval = TQString::number (0);
  874. break;
  875. default:
  876. lastJSCommandEntry = entry;
  877. type = KParts::LiveConnectExtension::TypeFunction;
  878. }
  879. return true;
  880. }
  881. KDE_NO_EXPORT bool KMPlayerLiveConnectExtension::put
  882. (const unsigned long, const TQString & name, const TQString & val) {
  883. if (name == "__kmplayer__res") {
  884. script_result = val;
  885. return true;
  886. }
  887. if (name.startsWith ("__kmplayer__obj_"))
  888. return !m_evaluating;
  889. kdDebug () << "put " << name << "=" << val << endl;
  890. const JSCommandEntry * entry = getJSCommandEntry (name.ascii ());
  891. if (!entry)
  892. return false;
  893. switch (entry->command) {
  894. case prop_source: {
  895. KURL url (val);
  896. if (player->allowRedir (url))
  897. player->openNewURL (url);
  898. break;
  899. }
  900. case prop_volume:
  901. if (player->view ())
  902. player->process()->viewer ()->view()->controlPanel()->volumeBar()->setValue(val.toInt ());
  903. break;
  904. default:
  905. return false;
  906. }
  907. return true;
  908. }
  909. KDE_NO_EXPORT bool KMPlayerLiveConnectExtension::call
  910. (const unsigned long id, const TQString & name,
  911. const TQStringList & args, KParts::LiveConnectExtension::Type & type,
  912. unsigned long & rid, TQString & rval) {
  913. const JSCommandEntry * entry = lastJSCommandEntry;
  914. const char * str = name.ascii ();
  915. if (!entry || strcmp (entry->name, str))
  916. entry = getJSCommandEntry (str);
  917. if (!entry)
  918. return false;
  919. kdDebug () << "entry " << entry->name << endl;
  920. for (unsigned int i = 0; i < args.size (); ++i)
  921. kdDebug () << " " << args[i] << endl;
  922. KMPlayer::View * view = static_cast <KMPlayer::View*> (player->view ());
  923. if (!view)
  924. return false;
  925. rid = id;
  926. type = entry->rettype;
  927. switch (entry->command) {
  928. case notsupported:
  929. if (entry->rettype != KParts::LiveConnectExtension::TypeVoid)
  930. rval = entry->defaultvalue;
  931. break;
  932. case canpause:
  933. rval = (player->process ()->playing () && !view->controlPanel()->button (KMPlayer::ControlPanel::button_pause)->isOn ()) ? "true" : "false";
  934. break;
  935. case canplay:
  936. rval = (!player->process ()->playing () || view->controlPanel()->button (KMPlayer::ControlPanel::button_pause)->isOn ()) ? "true" : "false";
  937. break;
  938. case canstop:
  939. rval = player->process ()->playing () ? "true" : "false";
  940. break;
  941. case canseek:
  942. rval = player->source ()->isSeekable () ? "true" : "false";
  943. break;
  944. case play:
  945. if (args.size ()) {
  946. KURL url (args.first ());
  947. if (player->allowRedir (url))
  948. player->openNewURL (url);
  949. } else
  950. player->play ();
  951. rval = "true";
  952. break;
  953. case start:
  954. player->play ();
  955. rval = "true";
  956. break;
  957. case stop:
  958. player->stop ();
  959. rval = "true";
  960. break;
  961. case showcontrolpanel:
  962. if (args.size () &&
  963. (args.first () == TQString::fromLatin1 ("0") ||
  964. args.first () == TQString::fromLatin1 ("false")))
  965. static_cast <KMPlayer::View*> (player->view ())->setControlPanelMode (KMPlayer::View::CP_Hide);
  966. else
  967. static_cast <KMPlayer::View*> (player->view ())->setControlPanelMode (KMPlayer::View::CP_Show);
  968. break;
  969. case jsc_pause:
  970. player->pause ();
  971. rval = "true";
  972. break;
  973. case isloop:
  974. rval = player->settings ()->loop ? "true" : "false";
  975. break;
  976. case isaspect:
  977. rval = player->settings ()->sizeratio ? "true" : "false";
  978. break;
  979. case isfullscreen:
  980. rval = static_cast <KMPlayer::View*> (player->view ())->isFullScreen () ? "true" : "false";
  981. break;
  982. case length:
  983. rval.setNum (player->source ()->length ());
  984. break;
  985. case width:
  986. rval.setNum (player->source ()->width ());
  987. break;
  988. case height:
  989. rval.setNum (player->source ()->height ());
  990. break;
  991. case playstate: // FIXME 0-6
  992. rval = player->process ()->playing () ? "3" : "0";
  993. break;
  994. case position:
  995. rval.setNum (player->position ());
  996. break;
  997. case protocol:
  998. rval = player->url ().protocol ();
  999. break;
  1000. case setsource:
  1001. rval ="false";
  1002. if (args.size ()) {
  1003. KURL url (args.first ());
  1004. if (player->allowRedir (url) && player->openNewURL (url))
  1005. rval = "true";
  1006. }
  1007. break;
  1008. case setvolume:
  1009. if (!args.size ())
  1010. return false;
  1011. player->process()->viewer ()->view()->controlPanel()->volumeBar()->setValue(args.first ().toInt ());
  1012. rval = "true";
  1013. break;
  1014. case source:
  1015. rval = player->url ().url ();
  1016. break;
  1017. case volume:
  1018. if (player->view ())
  1019. rval = TQString::number (player->process()->viewer ()->view()->controlPanel()->volumeBar()->value());
  1020. break;
  1021. default:
  1022. return false;
  1023. }
  1024. return true;
  1025. }
  1026. KDE_NO_EXPORT void KMPlayerLiveConnectExtension::unregister (const unsigned long) {
  1027. }
  1028. KDE_NO_EXPORT void KMPlayerLiveConnectExtension::setSize (int w, int h) {
  1029. KMPlayer::View * view = static_cast <KMPlayer::View*> (player->view ());
  1030. if (view->controlPanelMode () == KMPlayer::View::CP_Show)
  1031. h += view->controlPanel()->height();
  1032. TQString jscode;
  1033. jscode.sprintf("try { eval(\"this.setAttribute('WIDTH',%d);this.setAttribute('HEIGHT',%d)\"); } catch(e){}", w, h);
  1034. KParts::LiveConnectExtension::ArgList args;
  1035. args.push_back (qMakePair (KParts::LiveConnectExtension::TypeString, jscode));
  1036. emit partEvent (0, "eval", args);
  1037. }
  1038. //-----------------------------------------------------------------------------
  1039. KDE_NO_CDTOR_EXPORT KMPlayerHRefSource::KMPlayerHRefSource (PartBase * player)
  1040. : Source (i18n ("HREF"), player, "hrefsource") {
  1041. //kdDebug () << "KMPlayerHRefSource::KMPlayerHRefSource" << endl;
  1042. }
  1043. KDE_NO_CDTOR_EXPORT KMPlayerHRefSource::~KMPlayerHRefSource () {
  1044. //kdDebug () << "KMPlayerHRefSource::~KMPlayerHRefSource" << endl;
  1045. }
  1046. KDE_NO_EXPORT void KMPlayerHRefSource::init () {
  1047. Source::init ();
  1048. setIdentified ();
  1049. }
  1050. KDE_NO_EXPORT bool KMPlayerHRefSource::hasLength () {
  1051. return false;
  1052. }
  1053. KDE_NO_EXPORT bool KMPlayerHRefSource::processOutput (const TQString & /*str*/) {
  1054. //return Source::processOutput (str);
  1055. return true;
  1056. }
  1057. KDE_NO_EXPORT void KMPlayerHRefSource::setURL (const KURL & url) {
  1058. m_url = url;
  1059. m_identified = false;
  1060. m_finished = false;
  1061. Source::setURL (url);
  1062. kdDebug () << "KMPlayerHRefSource::setURL " << m_url.url() << endl;
  1063. }
  1064. KDE_NO_EXPORT void KMPlayerHRefSource::play () {
  1065. kdDebug () << "KMPlayerHRefSource::play " << m_url.url() << endl;
  1066. Source * src = m_player->sources () ["urlsource"];
  1067. TQString target = src->document ()->document ()->
  1068. getAttribute (StringPool::attr_target);
  1069. if (!target.isEmpty ()) {
  1070. KMPlayer::Mrl * mrl = src->document ()->mrl ();
  1071. static_cast <KMPlayerPart *> (m_player)->browserextension ()->requestOpenURL (mrl->src, target, mrl->mimetype);
  1072. } else
  1073. m_player->setSource (m_player->sources () ["urlsource"]);
  1074. }
  1075. KDE_NO_EXPORT void KMPlayerHRefSource::activate () {
  1076. m_player->stop ();
  1077. if (m_finished) {
  1078. TQTimer::singleShot (0, this, TQT_SLOT (finished ()));
  1079. return;
  1080. }
  1081. init ();
  1082. m_player->setProcess ("mplayer");
  1083. if (m_player->process ()->grabPicture (m_url, 0))
  1084. connect (m_player->process (), TQT_SIGNAL (grabReady (const TQString &)),
  1085. this, TQT_SLOT (grabReady (const TQString &)));
  1086. else {
  1087. setURL (KURL ());
  1088. TQTimer::singleShot (0, this, TQT_SLOT (play ()));
  1089. }
  1090. }
  1091. KDE_NO_EXPORT void KMPlayerHRefSource::clear () {
  1092. setURL (KURL ());
  1093. }
  1094. KDE_NO_EXPORT void KMPlayerHRefSource::grabReady (const TQString & path) {
  1095. kdDebug () << "KMPlayerHRefSource::grabReady(" << path << ")" << endl;
  1096. m_finished = true;
  1097. m_grabfile = path;
  1098. finished ();
  1099. }
  1100. KDE_NO_EXPORT void KMPlayerHRefSource::finished () {
  1101. kdDebug () << "KMPlayerHRefSource::finished()" << endl;
  1102. KMPlayer::View * view = static_cast <KMPlayer::View*> (m_player->view ());
  1103. if (!view) return;
  1104. if (!view->setPicture (m_grabfile)) {
  1105. clear ();
  1106. TQTimer::singleShot (0, this, TQT_SLOT (play ()));
  1107. return;
  1108. }
  1109. if (view->viewer ())
  1110. connect (view, TQT_SIGNAL (pictureClicked ()), this, TQT_SLOT (play ()));
  1111. }
  1112. KDE_NO_EXPORT void KMPlayerHRefSource::deactivate () {
  1113. kdDebug () << "KMPlayerHRefSource::deactivate()" << endl;
  1114. KMPlayer::View * view = static_cast <KMPlayer::View*> (m_player->view ());
  1115. if (!view) return;
  1116. view->setPicture (TQString ());
  1117. if (view->viewer ())
  1118. disconnect (view, TQT_SIGNAL (pictureClicked ()), this, TQT_SLOT (play ()));
  1119. }
  1120. KDE_NO_EXPORT TQString KMPlayerHRefSource::prettyName () {
  1121. return i18n ("WEB");
  1122. }
  1123. #include "kmplayer_part.moc"