|
|
|
/**
|
|
|
|
* Copyright (C) 2005-2007 by Koos Vriezen <koos.vriezen@gmail.com>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public License
|
|
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
#include <tqcolor.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqmovie.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqtextcodec.h>
|
|
|
|
#include <tqfont.h>
|
|
|
|
#include <tqapplication.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kurl.h>
|
|
|
|
#include <kmimetype.h>
|
|
|
|
#include <tdeio/job.h>
|
|
|
|
#include <tdeio/jobclasses.h>
|
|
|
|
|
|
|
|
#include "kmplayer_smil.h"
|
|
|
|
#include "kmplayer_rp.h"
|
|
|
|
|
|
|
|
using namespace KMPlayer;
|
|
|
|
|
|
|
|
namespace KMPlayer {
|
|
|
|
static const unsigned int event_activated = (unsigned int) Runtime::dur_activated;
|
|
|
|
const unsigned int event_inbounds = (unsigned int) Runtime::dur_inbounds;
|
|
|
|
const unsigned int event_outbounds = (unsigned int) Runtime::dur_outbounds;
|
|
|
|
static const unsigned int event_stopped = (unsigned int) Runtime::dur_end;
|
|
|
|
static const unsigned int event_started = (unsigned int)Runtime::dur_start;
|
|
|
|
static const unsigned int event_to_be_started = 1 + (unsigned int) Runtime::dur_last_dur;
|
|
|
|
const unsigned int event_pointer_clicked = (unsigned int) event_activated;
|
|
|
|
const unsigned int event_pointer_moved = (unsigned int) -11;
|
|
|
|
const unsigned int event_timer = (unsigned int) -12;
|
|
|
|
const unsigned int event_postponed = (unsigned int) -13;
|
|
|
|
const unsigned int mediatype_attached = (unsigned int) -14;
|
|
|
|
|
|
|
|
static const unsigned int started_timer_id = (unsigned int) 1;
|
|
|
|
static const unsigned int stopped_timer_id = (unsigned int) 2;
|
|
|
|
static const unsigned int start_timer_id = (unsigned int) 3;
|
|
|
|
static const unsigned int dur_timer_id = (unsigned int) 4;
|
|
|
|
static const unsigned int anim_timer_id = (unsigned int) 5;
|
|
|
|
static const unsigned int trans_timer_id = (unsigned int) 6;
|
|
|
|
static const unsigned int trans_out_timer_id = (unsigned int) 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Intrinsic duration
|
|
|
|
* duration_time | end_time |
|
|
|
|
* =======================================================================
|
|
|
|
* dur_media | dur_media | wait for event
|
|
|
|
* 0 | dur_media | only wait for child elements
|
|
|
|
* dur_media | 0 | intrinsic duration finished
|
|
|
|
*/
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool KMPlayer::parseTime (const TQString & vl, int & dur) {
|
|
|
|
const char * cval = vl.ascii ();
|
|
|
|
if (!cval) {
|
|
|
|
dur = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
int sign = 1;
|
|
|
|
bool fp_seen = false;
|
|
|
|
TQString num;
|
|
|
|
const char * p = cval;
|
|
|
|
for ( ; *p; p++ ) {
|
|
|
|
if (*p == '+') {
|
|
|
|
if (!num.isEmpty ())
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
sign = 1;
|
|
|
|
} else if (*p == '-') {
|
|
|
|
if (!num.isEmpty ())
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
sign = -1;
|
|
|
|
} else if (*p >= '0' && *p <= '9') {
|
|
|
|
num += TQChar (*p);
|
|
|
|
} else if (*p == '.') {
|
|
|
|
if (fp_seen)
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
num += TQChar (*p);
|
|
|
|
fp_seen = true;
|
|
|
|
} else if (*p == ' ') {
|
|
|
|
if (!num.isEmpty ())
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bool ok = false;
|
|
|
|
double t;
|
|
|
|
if (!num.isEmpty ())
|
|
|
|
t = sign * num.toDouble (&ok);
|
|
|
|
if (ok) {
|
|
|
|
dur = (unsigned int) (10 * t);
|
|
|
|
for ( ; *p; p++ ) {
|
|
|
|
if (*p == 'm') {
|
|
|
|
dur = (unsigned int) (t * 60);
|
|
|
|
break;
|
|
|
|
} else if (*p == 'h') {
|
|
|
|
dur = (unsigned int) (t * 60 * 60);
|
|
|
|
break;
|
|
|
|
} else if (*p != ' ')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dur = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static SMIL::Region * findRegion (NodePtr p, const TQString & id) {
|
|
|
|
TrieString regionname_attr ("regionName");
|
|
|
|
for (NodePtr c = p->firstChild (); c; c = c->nextSibling ()) {
|
|
|
|
if (c->id == SMIL::id_node_region) {
|
|
|
|
SMIL::Region * r = convertNode <SMIL::Region> (c);
|
|
|
|
TQString a = r->getAttribute (regionname_attr);
|
|
|
|
if (a.isEmpty ())
|
|
|
|
a = r->getAttribute (StringPool::attr_id);
|
|
|
|
if ((a.isEmpty () && id.isEmpty ()) || a == id) {
|
|
|
|
//kdDebug () << "MediaType region found " << id << endl;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SMIL::Region * r = findRegion (c, id);
|
|
|
|
if (r)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static SMIL::Transition * findTransition (NodePtr n, const TQString & id) {
|
|
|
|
SMIL::Smil * s = SMIL::Smil::findSmilNode (n);
|
|
|
|
if (s) {
|
|
|
|
Node * head = s->firstChild ().ptr ();
|
|
|
|
while (head && head->id != SMIL::id_node_head)
|
|
|
|
head = head->nextSibling ().ptr ();
|
|
|
|
if (head)
|
|
|
|
for (Node * c = head->firstChild (); c; c = c->nextSibling().ptr ())
|
|
|
|
if (c->id == SMIL::id_node_transition &&
|
|
|
|
id == static_cast <Element *> (c)->
|
|
|
|
getAttribute (StringPool::attr_id))
|
|
|
|
return static_cast <SMIL::Transition *> (c);
|
|
|
|
}
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static NodePtr findLocalNodeById (NodePtr n, const TQString & id) {
|
|
|
|
//kdDebug() << "findLocalNodeById " << id << endl;
|
|
|
|
SMIL::Smil * s = SMIL::Smil::findSmilNode (n);
|
|
|
|
if (s)
|
|
|
|
return s->document ()->getElementById (s, id, false);
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT ToBeStartedEvent::ToBeStartedEvent (NodePtr n)
|
|
|
|
: Event (event_to_be_started), node (n) {}
|
|
|
|
|
|
|
|
TimerEvent::TimerEvent (TimerInfoPtr tinfo)
|
|
|
|
: Event (event_timer), timer_info (tinfo), interval (false) {}
|
|
|
|
|
|
|
|
PostponedEvent::PostponedEvent (bool postponed)
|
|
|
|
: Event (event_postponed), is_postponed (postponed) {}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT Runtime::Runtime (NodePtr e)
|
|
|
|
: timingstate (timings_reset),
|
|
|
|
element (e), repeat_count (0) {}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT Runtime::~Runtime () {
|
|
|
|
if (start_timer || duration_timer) // ugh
|
|
|
|
reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Runtime::reset () {
|
|
|
|
if (element) {
|
|
|
|
if (start_timer) {
|
|
|
|
element->document ()->cancelTimer (start_timer);
|
|
|
|
ASSERT (!start_timer);
|
|
|
|
}
|
|
|
|
if (duration_timer) {
|
|
|
|
element->document ()->cancelTimer (duration_timer);
|
|
|
|
ASSERT (!duration_timer);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
start_timer = 0L;
|
|
|
|
duration_timer = 0L;
|
|
|
|
}
|
|
|
|
repeat_count = 0;
|
|
|
|
timingstate = timings_reset;
|
|
|
|
for (int i = 0; i < (int) durtime_last; i++) {
|
|
|
|
if (durations [i].connection)
|
|
|
|
durations [i].connection->disconnect ();
|
|
|
|
durations [i].durval = dur_timer;
|
|
|
|
durations [i].offset = 0;
|
|
|
|
}
|
|
|
|
endTime ().durval = dur_media;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void Runtime::setDurationItem (DurationTime item, const TQString & val) {
|
|
|
|
int dur = -2; // also 0 for 'media' duration, so it will not update then
|
|
|
|
TQString vs = val.stripWhiteSpace ();
|
|
|
|
TQString vl = vs.lower ();
|
|
|
|
const char * cval = vl.ascii ();
|
|
|
|
int offset = 0;
|
|
|
|
//kdDebug () << "setDuration1 " << vl << endl;
|
|
|
|
if (cval && cval[0]) {
|
|
|
|
TQString idref;
|
|
|
|
const char * p = cval;
|
|
|
|
if (parseTime (vl, offset)) {
|
|
|
|
dur = dur_timer;
|
|
|
|
} else if (!strncmp (cval, "id(", 3)) {
|
|
|
|
p = strchr (cval + 3, ')');
|
|
|
|
if (p) {
|
|
|
|
idref = vs.mid (3, p - cval - 3);
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
if (*p) {
|
|
|
|
const char *q = strchr (p, '(');
|
|
|
|
if (q)
|
|
|
|
p = q;
|
|
|
|
}
|
|
|
|
} else if (!strncmp (cval, "indefinite", 10)) {
|
|
|
|
dur = dur_infinite;
|
|
|
|
} else if (!strncmp (cval, "media", 5)) {
|
|
|
|
dur = dur_media;
|
|
|
|
}
|
|
|
|
if (dur == -2) {
|
|
|
|
NodePtr target;
|
|
|
|
const char * q = p;
|
|
|
|
if (idref.isEmpty ()) {
|
|
|
|
bool last_esc = false;
|
|
|
|
for ( ; *q; q++) {
|
|
|
|
if (*q == '\\') {
|
|
|
|
if (last_esc) {
|
|
|
|
idref += TQChar ('\\');
|
|
|
|
last_esc = false;
|
|
|
|
} else
|
|
|
|
last_esc = true;
|
|
|
|
} else if (*q == '.' && !last_esc) {
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
idref += TQChar (*q);
|
|
|
|
}
|
|
|
|
if (!*q)
|
|
|
|
idref = vs.mid (p - cval);
|
|
|
|
else
|
|
|
|
idref = vs.mid (p - cval, q - p);
|
|
|
|
}
|
|
|
|
++q;
|
|
|
|
if (!idref.isEmpty ()) {
|
|
|
|
target = findLocalNodeById (element, idref);
|
|
|
|
if (!target)
|
|
|
|
kdWarning () << "Element not found " << idref << endl;
|
|
|
|
}
|
|
|
|
//kdDebug () << "setDuration q:" << q << endl;
|
|
|
|
if (parseTime (vl.mid (q-cval), offset)) {
|
|
|
|
dur = dur_start;
|
|
|
|
} else if (*q && !strncmp (q, "end", 3)) {
|
|
|
|
dur = dur_end;
|
|
|
|
parseTime (vl.mid (q + 3 - cval), offset);
|
|
|
|
} else if (*q && !strncmp (q, "begin", 5)) {
|
|
|
|
dur = dur_start;
|
|
|
|
parseTime (vl.mid (q + 5 - cval), offset);
|
|
|
|
} else if (*q && !strncmp (q, "activateevent", 13)) {
|
|
|
|
dur = dur_activated;
|
|
|
|
parseTime (vl.mid (q + 13 - cval), offset);
|
|
|
|
} else if (*q && !strncmp (q, "inboundsevent", 13)) {
|
|
|
|
dur = dur_inbounds;
|
|
|
|
parseTime (vl.mid (q + 13 - cval), offset);
|
|
|
|
} else if (*q && !strncmp (q, "outofboundsevent", 16)) {
|
|
|
|
dur = dur_outbounds;
|
|
|
|
parseTime (vl.mid (q + 16 - cval), offset);
|
|
|
|
} else
|
|
|
|
kdWarning () << "setDuration no match " << cval << endl;
|
|
|
|
if (target && dur != dur_timer) {
|
|
|
|
durations [(int) item].connection =
|
|
|
|
target->connectTo (element, dur);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//kdDebug () << "setDuration " << dur << " id:'" << idref << "' off:" << offset << endl;
|
|
|
|
}
|
|
|
|
durations [(int) item].durval = (Duration) dur;
|
|
|
|
durations [(int) item].offset = offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start, or restart in case of re-use, the durations
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void Runtime::begin () {
|
|
|
|
if (!element) {
|
|
|
|
reset ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//kdDebug () << "Runtime::begin " << element->nodeName() << endl;
|
|
|
|
if (start_timer || duration_timer)
|
|
|
|
convertNode <SMIL::TimedMrl> (element)->init ();
|
|
|
|
timingstate = timings_began;
|
|
|
|
|
|
|
|
int offset = 0;
|
|
|
|
bool stop = true;
|
|
|
|
if (beginTime ().durval == dur_start) { // check started/finished
|
|
|
|
Connection * con = beginTime ().connection.ptr ();
|
|
|
|
if (con && con->connectee &&
|
|
|
|
con->connectee->state >= Node::state_began) {
|
|
|
|
offset = beginTime ().offset;
|
|
|
|
if (SMIL::TimedMrl::isTimedMrl (con->connectee))
|
|
|
|
offset -= element->document ()->last_event_time -
|
|
|
|
convertNode <SMIL::TimedMrl>(con->connectee)->begin_time;
|
|
|
|
stop = false;
|
|
|
|
kdWarning() << "start trigger on started element" << endl;
|
|
|
|
} // else wait for start event
|
|
|
|
} else if (beginTime ().durval == dur_end) { // check finished
|
|
|
|
Connection * con = beginTime ().connection.ptr ();
|
|
|
|
if (con && con->connectee &&
|
|
|
|
con->connectee->state >= Node::state_finished) {
|
|
|
|
int offset = beginTime ().offset;
|
|
|
|
if (SMIL::TimedMrl::isTimedMrl (con->connectee))
|
|
|
|
offset -= element->document ()->last_event_time -
|
|
|
|
convertNode<SMIL::TimedMrl>(con->connectee)->finish_time;
|
|
|
|
stop = false;
|
|
|
|
kdWarning() << "start trigger on finished element" << endl;
|
|
|
|
} // else wait for end event
|
|
|
|
} else if (beginTime ().durval == dur_timer) {
|
|
|
|
offset = beginTime ().offset;
|
|
|
|
stop = false;
|
|
|
|
}
|
|
|
|
if (stop) // wait for event
|
|
|
|
propagateStop (false);
|
|
|
|
else if (offset > 0) // start timer
|
|
|
|
start_timer = element->document ()->setTimeout (
|
|
|
|
element, 100 * offset, start_timer_id);
|
|
|
|
else // start now
|
|
|
|
propagateStart ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Runtime::beginAndStart () {
|
|
|
|
if (element) {
|
|
|
|
if (start_timer || duration_timer)
|
|
|
|
convertNode <SMIL::TimedMrl> (element)->init ();
|
|
|
|
timingstate = timings_began;
|
|
|
|
propagateStart ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
bool Runtime::parseParam (const TrieString & name, const TQString & val) {
|
|
|
|
//kdDebug () << "Runtime::parseParam " << name << "=" << val << endl;
|
|
|
|
if (name == StringPool::attr_begin) {
|
|
|
|
setDurationItem (begin_time, val);
|
|
|
|
if ((timingstate == timings_began && !start_timer) ||
|
|
|
|
timingstate == timings_stopped) {
|
|
|
|
if (beginTime ().offset > 0) { // create a timer for start
|
|
|
|
if (start_timer)
|
|
|
|
element->document ()->cancelTimer (start_timer);
|
|
|
|
if (beginTime ().durval == dur_timer)
|
|
|
|
start_timer = element->document ()->setTimeout
|
|
|
|
(element, 100 * beginTime ().offset, start_timer_id);
|
|
|
|
} else // start now
|
|
|
|
propagateStart ();
|
|
|
|
}
|
|
|
|
} else if (name == StringPool::attr_dur) {
|
|
|
|
setDurationItem (duration_time, val);
|
|
|
|
} else if (name == StringPool::attr_end) {
|
|
|
|
setDurationItem (end_time, val);
|
|
|
|
if (endTime ().durval == dur_timer &&
|
|
|
|
endTime ().offset > beginTime ().offset)
|
|
|
|
durTime ().offset = endTime ().offset - beginTime ().offset;
|
|
|
|
else if (endTime ().durval != dur_timer)
|
|
|
|
durTime ().durval = dur_media; // event
|
|
|
|
} else if (name == StringPool::attr_title) {
|
|
|
|
Mrl * mrl = static_cast <Mrl *> (element.ptr ());
|
|
|
|
if (mrl)
|
|
|
|
mrl->pretty_name = val;
|
|
|
|
} else if (name == "endsync") {
|
|
|
|
if ((durTime ().durval == dur_media || durTime ().durval == 0) &&
|
|
|
|
endTime ().durval == dur_media) {
|
|
|
|
NodePtr e = findLocalNodeById (element, val);
|
|
|
|
if (SMIL::TimedMrl::isTimedMrl (e)) {
|
|
|
|
SMIL::TimedMrl * tm = static_cast <SMIL::TimedMrl *> (e.ptr ());
|
|
|
|
durations [(int) end_time].connection =
|
|
|
|
tm->connectTo (element, event_stopped);
|
|
|
|
durations [(int) end_time].durval = (Duration) event_stopped;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (name.startsWith ("repeat")) {
|
|
|
|
if (val.find ("indefinite") > -1)
|
|
|
|
repeat_count = dur_infinite;
|
|
|
|
else
|
|
|
|
repeat_count = val.toInt ();
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Runtime::processEvent (unsigned int event) {
|
|
|
|
SMIL::TimedMrl * tm = convertNode <SMIL::TimedMrl> (element);
|
|
|
|
if (tm) {
|
|
|
|
if (timingstate != timings_started && beginTime ().durval == event) {
|
|
|
|
if (start_timer)
|
|
|
|
element->document ()->cancelTimer (start_timer);
|
|
|
|
if (element && beginTime ().offset > 0)
|
|
|
|
start_timer = element->document ()->setTimeout (element,
|
|
|
|
100 * beginTime ().offset, start_timer_id);
|
|
|
|
else //FIXME neg. offsets
|
|
|
|
propagateStart ();
|
|
|
|
if (tm->state == Node::state_finished)
|
|
|
|
tm->state = Node::state_activated; // rewind to activated
|
|
|
|
} else if (timingstate == timings_started &&
|
|
|
|
(unsigned int) endTime ().durval == event)
|
|
|
|
propagateStop (true);
|
|
|
|
} else
|
|
|
|
reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Runtime::propagateStop (bool forced) {
|
|
|
|
if (state() == timings_reset || state() == timings_stopped)
|
|
|
|
return; // nothing to stop
|
|
|
|
if (!forced && element) {
|
|
|
|
if (durTime ().durval == dur_media && endTime ().durval == dur_media)
|
|
|
|
return; // wait for external eof
|
|
|
|
if (endTime ().durval != dur_timer && endTime ().durval != dur_media &&
|
|
|
|
(state() == timings_started || beginTime().durval == dur_timer))
|
|
|
|
return; // wait for event
|
|
|
|
if (durTime ().durval == dur_infinite)
|
|
|
|
return; // this may take a while :-)
|
|
|
|
if (duration_timer)
|
|
|
|
return; // timerEvent will call us with forced=true
|
|
|
|
// bail out if a child still running
|
|
|
|
for (NodePtr c = element->firstChild (); c; c = c->nextSibling ())
|
|
|
|
if (c->unfinished ())
|
|
|
|
return; // a child still running
|
|
|
|
}
|
|
|
|
bool was_started (timingstate == timings_started);
|
|
|
|
timingstate = timings_stopped;
|
|
|
|
if (element) {
|
|
|
|
if (start_timer) {
|
|
|
|
element->document ()->cancelTimer (start_timer);
|
|
|
|
ASSERT (!start_timer);
|
|
|
|
}
|
|
|
|
if (duration_timer) {
|
|
|
|
element->document ()->cancelTimer (duration_timer);
|
|
|
|
ASSERT (!duration_timer);
|
|
|
|
}
|
|
|
|
if (was_started && element->document ()->active ())
|
|
|
|
element->document ()->setTimeout (element, 0, stopped_timer_id);
|
|
|
|
else if (element->unfinished ())
|
|
|
|
element->finish ();
|
|
|
|
} else {
|
|
|
|
start_timer = 0L;
|
|
|
|
duration_timer = 0L;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Runtime::propagateStart () {
|
|
|
|
SMIL::TimedMrl * tm = convertNode <SMIL::TimedMrl> (element);
|
|
|
|
if (tm) {
|
|
|
|
tm->propagateEvent (new ToBeStartedEvent (element));
|
|
|
|
if (start_timer)
|
|
|
|
tm->document ()->cancelTimer (start_timer);
|
|
|
|
ASSERT (!start_timer);
|
|
|
|
} else
|
|
|
|
start_timer = 0L;
|
|
|
|
timingstate = timings_started;
|
|
|
|
element->document ()->setTimeout (element, 0, started_timer_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start_timer timer expired
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void Runtime::started () {
|
|
|
|
//kdDebug () << "Runtime::started " << (element ? element->nodeName() : "-") << endl;
|
|
|
|
NodePtr e = element; // element is weak
|
|
|
|
SMIL::TimedMrl * tm = convertNode <SMIL::TimedMrl> (e);
|
|
|
|
if (tm) {
|
|
|
|
if (start_timer)
|
|
|
|
tm->document ()->cancelTimer (start_timer);
|
|
|
|
if (durTime ().offset > 0 && durTime ().durval == dur_timer) {
|
|
|
|
if (duration_timer)
|
|
|
|
tm->document ()->cancelTimer (duration_timer);
|
|
|
|
duration_timer = element->document ()->setTimeout
|
|
|
|
(element, 100 * durTime ().offset, dur_timer_id);
|
|
|
|
}
|
|
|
|
// kdDebug () << "Runtime::started set dur timer " << durTime ().offset << endl;
|
|
|
|
tm->propagateEvent (new Event (event_started));
|
|
|
|
tm->begin ();
|
|
|
|
} else
|
|
|
|
reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* duration_timer timer expired or no duration set after started
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void Runtime::stopped () {
|
|
|
|
if (!element) {
|
|
|
|
reset ();
|
|
|
|
} else if (element->active ()) {
|
|
|
|
if (repeat_count == dur_infinite || 0 < repeat_count--) {
|
|
|
|
if (beginTime ().offset > 0 &&
|
|
|
|
beginTime ().durval == dur_timer) {
|
|
|
|
if (start_timer)
|
|
|
|
element->document ()->cancelTimer (start_timer);
|
|
|
|
start_timer = element->document ()->setTimeout
|
|
|
|
(element, 100 * beginTime ().offset, start_timer_id);
|
|
|
|
} else {
|
|
|
|
propagateStart ();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
repeat_count = 0;
|
|
|
|
element->finish ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SizeType::SizeType () {
|
|
|
|
reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SizeType::SizeType (const TQString & s) {
|
|
|
|
*this = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SizeType::reset () {
|
|
|
|
perc_size = 0;
|
|
|
|
abs_size = 0;
|
|
|
|
isset = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
SizeType & SizeType::operator = (const TQString & s) {
|
|
|
|
TQString strval (s);
|
|
|
|
int p = strval.find (TQChar ('%'));
|
|
|
|
if (p > -1) {
|
|
|
|
strval.truncate (p);
|
|
|
|
perc_size = strval.toDouble (&isset);
|
|
|
|
} else
|
|
|
|
abs_size = strval.toDouble (&isset);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
SizeType & SizeType::operator += (const SizeType & s) {
|
|
|
|
perc_size += s.perc_size;
|
|
|
|
abs_size += s.abs_size;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
SizeType & SizeType::operator -= (const SizeType & s) {
|
|
|
|
perc_size -= s.perc_size;
|
|
|
|
abs_size -= s.abs_size;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Single SizeType::size (Single relative_to) const {
|
|
|
|
Single s = abs_size;
|
|
|
|
s += perc_size * relative_to / 100;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------%<----------------------------------------------------------
|
|
|
|
|
|
|
|
SRect SRect::unite (const SRect & r) const {
|
|
|
|
if (!(_w > 0 && _h > 0))
|
|
|
|
return r;
|
|
|
|
if (!(r._w > 0 && r._h > 0))
|
|
|
|
return *this;
|
|
|
|
Single a (_x < r._x ? _x : r._x);
|
|
|
|
Single b (_y < r._y ? _y : r._y);
|
|
|
|
return SRect (a, b,
|
|
|
|
((_x + _w < r._x + r._w) ? r._x + r._w : _x + _w) - a,
|
|
|
|
((_y + _h < r._y + r._h) ? r._y + r._h : _y + _h) - b);
|
|
|
|
}
|
|
|
|
|
|
|
|
SRect SRect::intersect (const SRect & r) const {
|
|
|
|
Single a (_x < r._x ? r._x : _x);
|
|
|
|
Single b (_y < r._y ? r._y : _y);
|
|
|
|
return SRect (a, b,
|
|
|
|
((_x + _w < r._x + r._w) ? _x + _w : r._x + r._w) - a,
|
|
|
|
((_y + _h < r._y + r._h) ? _y + _h : r._y + r._h) - b);
|
|
|
|
}
|
|
|
|
|
|
|
|
IRect IRect::unite (const IRect & r) const {
|
|
|
|
if (isEmpty ())
|
|
|
|
return r;
|
|
|
|
if (r.isEmpty ())
|
|
|
|
return *this;
|
|
|
|
int a (x < r.x ? x : r.x);
|
|
|
|
int b (y < r.y ? y : r.y);
|
|
|
|
return IRect (a, b,
|
|
|
|
((x + w < r.x + r.w) ? r.x + r.w : x + w) - a,
|
|
|
|
((y + h < r.y + r.h) ? r.y + r.h : y + h) - b);
|
|
|
|
}
|
|
|
|
|
|
|
|
IRect IRect::intersect (const IRect & r) const {
|
|
|
|
int a (x < r.x ? r.x : x);
|
|
|
|
int b (y < r.y ? r.y : y);
|
|
|
|
return IRect (a, b,
|
|
|
|
((x + w < r.x + r.w) ? x + w : r.x + r.w) - a,
|
|
|
|
((y + h < r.y + r.h) ? y + h : r.y + r.h) - b);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void CalculatedSizer::resetSizes () {
|
|
|
|
left.reset ();
|
|
|
|
top.reset ();
|
|
|
|
width.reset ();
|
|
|
|
height.reset ();
|
|
|
|
right.reset ();
|
|
|
|
bottom.reset ();
|
|
|
|
reg_point.truncate (0);
|
|
|
|
reg_align = TQString::fromLatin1 ("topLeft");
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool regPoints (const TQString & str, Single & x, Single & y) {
|
|
|
|
TQString lower = str.lower ();
|
|
|
|
const char * rp = lower.ascii ();
|
|
|
|
if (!rp)
|
|
|
|
return false;
|
|
|
|
if (!strcmp (rp, "center")) {
|
|
|
|
x = 50;
|
|
|
|
y = 50;
|
|
|
|
} else {
|
|
|
|
if (!strncmp (rp, "top", 3)) {
|
|
|
|
y = 0;
|
|
|
|
rp += 3;
|
|
|
|
} else if (!strncmp (rp, "mid", 3)) {
|
|
|
|
y = 50;
|
|
|
|
rp += 3;
|
|
|
|
} else if (!strncmp (rp, "bottom", 6)) {
|
|
|
|
y = 100;
|
|
|
|
rp += 6;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
if (!strcmp (rp, "left")) {
|
|
|
|
x = 0;
|
|
|
|
} else if (!strcmp (rp, "mid")) {
|
|
|
|
x = 50;
|
|
|
|
} else if (!strcmp (rp, "right")) {
|
|
|
|
x = 100;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
bool CalculatedSizer::applyRegPoints (Node * node, Single w, Single h,
|
|
|
|
Single & xoff, Single & yoff, Single & w1, Single & h1) {
|
|
|
|
if (reg_point.isEmpty ())
|
|
|
|
return false;
|
|
|
|
Single rpx, rpy, rax, ray;
|
|
|
|
if (!regPoints (reg_point, rpx, rpy)) {
|
|
|
|
node = SMIL::Smil::findSmilNode (node);
|
|
|
|
if (!node)
|
|
|
|
return false;
|
|
|
|
node = static_cast <SMIL::Smil *> (node)->layout_node.ptr ();
|
|
|
|
if (!node)
|
|
|
|
return false;
|
|
|
|
NodePtr c = node->firstChild ();
|
|
|
|
for (; c; c = c->nextSibling ())
|
|
|
|
if (c->id == SMIL::id_node_regpoint &&
|
|
|
|
convertNode<Element>(c)->getAttribute (StringPool::attr_id)
|
|
|
|
== reg_point) {
|
|
|
|
Single i1, i2; // dummies
|
|
|
|
SMIL::RegPoint *rp_elm = static_cast<SMIL::RegPoint*>(c.ptr());
|
|
|
|
rp_elm->sizes.calcSizes (0L, 100, 100, rpx, rpy, i1, i2);
|
|
|
|
TQString ra = rp_elm->getAttribute ("regAlign");
|
|
|
|
if (!ra.isEmpty () && reg_align.isEmpty ())
|
|
|
|
reg_align = ra;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!c)
|
|
|
|
return false; // not found
|
|
|
|
}
|
|
|
|
if (!regPoints (reg_align, rax, ray))
|
|
|
|
rax = ray = 0; // default back to topLeft
|
|
|
|
if (!(int)w1 || !(int)h1) {
|
|
|
|
xoff = w * (rpx - rax) / 100;
|
|
|
|
yoff = h * (rpy - ray) / 100;
|
|
|
|
w1 = w - w * (rpx > rax ? (rpx - rax) : (rax - rpx)) / 100;
|
|
|
|
h1 = h - h * (rpy > ray ? (rpy - ray) : (ray - rpy)) / 100;
|
|
|
|
} else {
|
|
|
|
xoff = (w * rpx - w1 * rax) / 100;
|
|
|
|
yoff = (h * rpy - h1 * ray) / 100;
|
|
|
|
}
|
|
|
|
// kdDebug () << "calc rp:" << reg_point << " ra:" << reg_align << " w:" << (int)w << " h:" << (int)h << " xoff:" << (int)xoff << " yoff:" << (int)yoff << " w1:" << (int)w1 << " h1:" << (int)h1 << endl;
|
|
|
|
return true; // success getting sizes based on regPoint
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void CalculatedSizer::calcSizes (Node * node, Single w, Single h,
|
|
|
|
Single & xoff, Single & yoff, Single & w1, Single & h1) {
|
|
|
|
if (applyRegPoints (node, w, h, xoff, yoff, w1, h1))
|
|
|
|
return;
|
|
|
|
if (left.isSet ())
|
|
|
|
xoff = left.size (w);
|
|
|
|
else if (width.isSet ()) {
|
|
|
|
if (right.isSet ())
|
|
|
|
xoff = w - width.size (w) - right.size (w);
|
|
|
|
else
|
|
|
|
xoff = (w - width.size (w)) / 2;
|
|
|
|
} else
|
|
|
|
xoff = 0;
|
|
|
|
if (top.isSet ())
|
|
|
|
yoff = top.size (h);
|
|
|
|
else if (height.isSet ()) {
|
|
|
|
if (bottom.isSet ())
|
|
|
|
yoff = h - height.size (h) - bottom.size (h);
|
|
|
|
else
|
|
|
|
yoff = (h - height.size (h)) / 2;
|
|
|
|
} else
|
|
|
|
yoff = 0;
|
|
|
|
if (width.isSet ())
|
|
|
|
w1 = width.size (w);
|
|
|
|
else if (right.isSet ())
|
|
|
|
w1 = w - xoff - right.size (w);
|
|
|
|
else
|
|
|
|
w1 = w - xoff;
|
|
|
|
if (w1 < 0)
|
|
|
|
w1 = 0;
|
|
|
|
if (height.isSet ())
|
|
|
|
h1 = height.size (h);
|
|
|
|
else if (bottom.isSet ())
|
|
|
|
h1 = h - yoff - bottom.size (h);
|
|
|
|
else
|
|
|
|
h1 = h - yoff;
|
|
|
|
if (h1 < 0)
|
|
|
|
h1 = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
bool CalculatedSizer::setSizeParam(const TrieString &name, const TQString &val, bool &dim_changed) {
|
|
|
|
dim_changed = true;
|
|
|
|
if (name == StringPool::attr_left) {
|
|
|
|
left = val;
|
|
|
|
dim_changed = right.isSet ();
|
|
|
|
} else if (name == StringPool::attr_top) {
|
|
|
|
top = val;
|
|
|
|
dim_changed = bottom.isSet ();
|
|
|
|
} else if (name == StringPool::attr_width) {
|
|
|
|
width = val;
|
|
|
|
} else if (name == StringPool::attr_height) {
|
|
|
|
height = val;
|
|
|
|
} else if (name == StringPool::attr_right) {
|
|
|
|
right = val;
|
|
|
|
dim_changed = left.isSet ();
|
|
|
|
} else if (name == StringPool::attr_bottom) {
|
|
|
|
bottom = val;
|
|
|
|
dim_changed = top.isSet ();
|
|
|
|
} else if (name == "regPoint") {
|
|
|
|
reg_point = val;
|
|
|
|
dim_changed = false;
|
|
|
|
} else if (name == "regAlign") {
|
|
|
|
reg_align = val;
|
|
|
|
dim_changed = false;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void
|
|
|
|
CalculatedSizer::move (const SizeType &x, const SizeType &y) {
|
|
|
|
if (left.isSet ()) {
|
|
|
|
if (right.isSet ()) {
|
|
|
|
right += x;
|
|
|
|
right -= left;
|
|
|
|
}
|
|
|
|
left = x;
|
|
|
|
} else if (right.isSet ()) {
|
|
|
|
right = x;
|
|
|
|
} else {
|
|
|
|
left = x;
|
|
|
|
}
|
|
|
|
if (top.isSet ()) {
|
|
|
|
if (bottom.isSet ()) {
|
|
|
|
bottom += y;
|
|
|
|
bottom -= top;
|
|
|
|
}
|
|
|
|
top = y;
|
|
|
|
} else if (bottom.isSet ()) {
|
|
|
|
bottom = y;
|
|
|
|
} else {
|
|
|
|
top = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT AnimateGroupData::AnimateGroupData (NodePtr e)
|
|
|
|
: Runtime (e), modification_id (-1) {}
|
|
|
|
|
|
|
|
bool AnimateGroupData::parseParam (const TrieString &name, const TQString &val) {
|
|
|
|
//kdDebug () << "AnimateGroupData::parseParam " << name << "=" << val << endl;
|
|
|
|
if (name == StringPool::attr_target || name == "targetElement") {
|
|
|
|
if (element)
|
|
|
|
target_element = findLocalNodeById (element, val);
|
|
|
|
} else if (name == "attribute" || name == "attributeName") {
|
|
|
|
changed_attribute = TrieString (val);
|
|
|
|
} else if (name == "to") {
|
|
|
|
change_to = val;
|
|
|
|
} else
|
|
|
|
return Runtime::parseParam (name, val);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* animation finished
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void AnimateGroupData::stopped () {
|
|
|
|
//kdDebug () << "AnimateGroupData::stopped " << durTime ().durval << endl;
|
|
|
|
if (!SMIL::TimedMrl::keepContent (element))
|
|
|
|
restoreModification ();
|
|
|
|
Runtime::stopped ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateGroupData::reset () {
|
|
|
|
restoreModification ();
|
|
|
|
Runtime::reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateGroupData::restoreModification () {
|
|
|
|
if (modification_id > -1 && target_element &&
|
|
|
|
target_element->state > Node::state_init) {
|
|
|
|
//kdDebug () << "AnimateGroupData(" << this << ")::restoreModificatio " <<modification_id << endl;
|
|
|
|
convertNode <Element> (target_element)->resetParam (
|
|
|
|
changed_attribute, modification_id);
|
|
|
|
}
|
|
|
|
modification_id = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start_timer timer expired, execute it
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void SetData::started () {
|
|
|
|
restoreModification ();
|
|
|
|
if (element) {
|
|
|
|
if (target_element) {
|
|
|
|
convertNode <Element> (target_element)->setParam (
|
|
|
|
changed_attribute, change_to, &modification_id);
|
|
|
|
//kdDebug () << "SetData(" << this << ")::started " << target_element->nodeName () << "." << changed_attribute << " ->" << change_to << " modid:" << modification_id << endl;
|
|
|
|
} else
|
|
|
|
kdWarning () << "target element not found" << endl;
|
|
|
|
} else
|
|
|
|
kdWarning () << "set element disappeared" << endl;
|
|
|
|
AnimateGroupData::started ();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//http://en.wikipedia.org/wiki/B%C3%A9zier_curve
|
|
|
|
typedef struct {
|
|
|
|
float x;
|
|
|
|
float y;
|
|
|
|
} Point2D;
|
|
|
|
|
|
|
|
static Point2D PointOnCubicBezier (Point2D *cp, float t) {
|
|
|
|
float ax, bx, cx;
|
|
|
|
float ay, by, cy;
|
|
|
|
float tSquared, tCubed;
|
|
|
|
Point2D result;
|
|
|
|
|
|
|
|
/* calculate the polynomial coefficients */
|
|
|
|
|
|
|
|
cx = 3.0 * (cp[1].x - cp[0].x);
|
|
|
|
bx = 3.0 * (cp[2].x - cp[1].x) - cx;
|
|
|
|
ax = cp[3].x - cp[0].x - cx - bx;
|
|
|
|
|
|
|
|
cy = 3.0 * (cp[1].y - cp[0].y);
|
|
|
|
by = 3.0 * (cp[2].y - cp[1].y) - cy;
|
|
|
|
ay = cp[3].y - cp[0].y - cy - by;
|
|
|
|
|
|
|
|
/* calculate the curve point at parameter value t */
|
|
|
|
|
|
|
|
tSquared = t * t;
|
|
|
|
tCubed = tSquared * t;
|
|
|
|
|
|
|
|
result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
|
|
|
|
result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT AnimateData::AnimateData (NodePtr e)
|
|
|
|
: AnimateGroupData (e), change_by (0), steps (0) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateData::reset () {
|
|
|
|
AnimateGroupData::reset ();
|
|
|
|
if (element) {
|
|
|
|
if (anim_timer)
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
ASSERT (!anim_timer);
|
|
|
|
} else
|
|
|
|
anim_timer = 0;
|
|
|
|
accumulate = acc_none;
|
|
|
|
additive = add_replace;
|
|
|
|
change_by = 0;
|
|
|
|
calcMode = calc_linear;
|
|
|
|
change_from.truncate (0);
|
|
|
|
change_values.clear ();
|
|
|
|
steps = 0;
|
|
|
|
change_delta = change_to_val = change_from_val = 0.0;
|
|
|
|
change_from_unit.truncate (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AnimateData::parseParam (const TrieString & name, const TQString & val) {
|
|
|
|
//kdDebug () << "AnimateData::parseParam " << name << "=" << val << endl;
|
|
|
|
if (name == "change_by") {
|
|
|
|
change_by = val.toInt ();
|
|
|
|
} else if (name == "from") {
|
|
|
|
change_from = val;
|
|
|
|
} else if (name == "values") {
|
|
|
|
change_values = TQStringList::split (TQString (";"), val);
|
|
|
|
} else if (name == "calcMode") {
|
|
|
|
if (val == TQString::fromLatin1 ("discrete"))
|
|
|
|
calcMode = calc_discrete;
|
|
|
|
else if (val == TQString::fromLatin1 ("linear"))
|
|
|
|
calcMode = calc_linear;
|
|
|
|
else if (val == TQString::fromLatin1 ("paced"))
|
|
|
|
calcMode = calc_paced;
|
|
|
|
} else
|
|
|
|
return AnimateGroupData::parseParam (name, val);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start_timer timer expired, execute it
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void AnimateData::started () {
|
|
|
|
//kdDebug () << "AnimateData::started " << durTime ().durval << endl;
|
|
|
|
restoreModification ();
|
|
|
|
if (anim_timer) {
|
|
|
|
kdWarning () << "AnimateData::started " << anim_timer.ptr() << endl;
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
}
|
|
|
|
bool success = false;
|
|
|
|
do {
|
|
|
|
if (!element) {
|
|
|
|
kdWarning () << "set element disappeared" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
NodePtr protect = target_element;
|
|
|
|
Element * target = convertNode <Element> (target_element);
|
|
|
|
if (!target) {
|
|
|
|
kdWarning () << "target element not found" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (calcMode == calc_linear) {
|
|
|
|
TQRegExp reg ("^\\s*(-?[0-9\\.]+)(\\s*[%a-z]*)?");
|
|
|
|
if (change_from.isEmpty ()) {
|
|
|
|
if (change_values.size () > 0) // check 'values' attribute
|
|
|
|
change_from = change_values.first ();
|
|
|
|
else // take current
|
|
|
|
change_from = target->param (changed_attribute);
|
|
|
|
}
|
|
|
|
if (!change_from.isEmpty ()) {
|
|
|
|
target->setParam (changed_attribute, change_from,
|
|
|
|
&modification_id);
|
|
|
|
if (reg.search (change_from) > -1) {
|
|
|
|
change_from_val = reg.cap (1).toDouble ();
|
|
|
|
change_from_unit = reg.cap (2);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
kdWarning() << "animate couldn't determine start value" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (change_to.isEmpty () && change_values.size () > 1)
|
|
|
|
change_to = change_values.last (); // check 'values' attribute
|
|
|
|
if (!change_to.isEmpty () && reg.search (change_to) > -1) {
|
|
|
|
change_to_val = reg.cap (1).toDouble ();
|
|
|
|
} else {
|
|
|
|
kdWarning () << "animate couldn't determine end value" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
steps = 20 * durTime ().offset / 5; // 40 per sec
|
|
|
|
if (steps > 0) {
|
|
|
|
anim_timer = element->document ()->setTimeout (element, 25, anim_timer_id); // 25 ms for now FIXME
|
|
|
|
change_delta = (change_to_val - change_from_val) / steps;
|
|
|
|
//kdDebug () << "AnimateData::started " << target_element->nodeName () << "." << changed_attribute << " " << change_from_val << "->" << change_to_val << " in " << steps << " using:" << change_delta << " inc" << endl;
|
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
} else if (calcMode == calc_discrete) {
|
|
|
|
steps = change_values.size () - 1; // we do already the first step
|
|
|
|
if (steps < 1) {
|
|
|
|
kdWarning () << "animate needs at least two values" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
int interval = 100 * durTime ().offset / (1 + steps);
|
|
|
|
if (interval <= 0 || durTime ().durval != dur_timer) {
|
|
|
|
kdWarning () << "animate needs a duration time" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//kdDebug () << "AnimateData::started " << target_element->nodeName () << "." << changed_attribute << " " << change_values.first () << "->" << change_values.last () << " in " << steps << " interval:" << interval << endl;
|
|
|
|
anim_timer = element->document ()->setTimeout (element, interval, anim_timer_id); // 50 /s for now FIXME
|
|
|
|
target->setParam (changed_attribute, change_values.first (),
|
|
|
|
&modification_id);
|
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
} while (false);
|
|
|
|
if (success)
|
|
|
|
AnimateGroupData::started ();
|
|
|
|
else
|
|
|
|
propagateStop (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* undo if necessary
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void AnimateData::stopped () {
|
|
|
|
if (element) {
|
|
|
|
if (anim_timer) // make sure timers are stopped
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
ASSERT (!anim_timer);
|
|
|
|
if (steps > 0 && element->active ()) {
|
|
|
|
steps = 0;
|
|
|
|
if (calcMode == calc_linear)
|
|
|
|
change_from_val = change_to_val;
|
|
|
|
applyStep (); // we lost some steps ..
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
anim_timer = 0;
|
|
|
|
AnimateGroupData::stopped ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateData::applyStep () {
|
|
|
|
Element * target = convertNode <Element> (target_element);
|
|
|
|
if (target && calcMode == calc_linear)
|
|
|
|
target->setParam (changed_attribute, TQString ("%1%2").arg (
|
|
|
|
change_from_val).arg(change_from_unit),
|
|
|
|
&modification_id);
|
|
|
|
else if (target && calcMode == calc_discrete)
|
|
|
|
target->setParam (changed_attribute,
|
|
|
|
change_values[change_values.size () - steps -1],
|
|
|
|
&modification_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* for animations
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT bool AnimateData::timerTick () {
|
|
|
|
if (!anim_timer) {
|
|
|
|
kdError () << "spurious anim timer tick" << endl;
|
|
|
|
} else if (steps-- > 0) {
|
|
|
|
if (calcMode == calc_linear)
|
|
|
|
change_from_val += change_delta;
|
|
|
|
applyStep ();
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if (element)
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
ASSERT (!anim_timer);
|
|
|
|
propagateStop (true); // not sure, actually
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT AnimateMotionData::AnimateMotionData (NodePtr e)
|
|
|
|
: AnimateGroupData (e), keytimes (NULL), steps (0) {}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT AnimateMotionData::~AnimateMotionData () {
|
|
|
|
reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AnimateMotionData::checkTarget (Node *n) {
|
|
|
|
if (!n ||
|
|
|
|
(SMIL::id_node_region != n->id &&
|
|
|
|
!(SMIL::id_node_first_mediatype <= n->id &&
|
|
|
|
SMIL::id_node_last_mediatype >= n->id))) {
|
|
|
|
kdWarning () << "animateMotion target element not " <<
|
|
|
|
(n ? "supported" : "found") << endl;
|
|
|
|
if (element && anim_timer)
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
propagateStop (true);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateMotionData::reset () {
|
|
|
|
AnimateGroupData::reset ();
|
|
|
|
if (element) {
|
|
|
|
if (anim_timer)
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
ASSERT (!anim_timer);
|
|
|
|
} else
|
|
|
|
anim_timer = 0;
|
|
|
|
accumulate = acc_none;
|
|
|
|
additive = add_replace;
|
|
|
|
calcMode = calc_linear;
|
|
|
|
change_from.truncate (0);
|
|
|
|
change_by.truncate (0);
|
|
|
|
values.clear ();
|
|
|
|
delete keytimes;
|
|
|
|
keytimes = NULL;
|
|
|
|
keytime_count = 0;
|
|
|
|
splines.clear ();
|
|
|
|
steps = 0;
|
|
|
|
cur_x = cur_y = delta_x = delta_y = SizeType();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AnimateMotionData::parseParam (const TrieString & name, const TQString & val) {
|
|
|
|
//kdDebug () << "AnimateMotionData::parseParam " << name << "=" << val << endl;
|
|
|
|
if (name == "from") {
|
|
|
|
change_from = val;
|
|
|
|
} else if (name == "by") {
|
|
|
|
change_by = val;
|
|
|
|
} else if (name == "values") {
|
|
|
|
values = TQStringList::split (TQString (";"), val);
|
|
|
|
} else if (name == "keyTimes") {
|
|
|
|
TQStringList kts = TQStringList::split (TQString (";"), val);
|
|
|
|
delete keytimes;
|
|
|
|
keytime_count = kts.size ();
|
|
|
|
keytimes = new float [keytime_count];
|
|
|
|
for (int i = 0; i < keytime_count; i++) {
|
|
|
|
keytimes[i] = kts[i].stripWhiteSpace().toDouble();
|
|
|
|
if (keytimes[i] < 0.0 || keytimes[i] > 1.0)
|
|
|
|
kdWarning() << "animateMotion wrong keyTimes values" << endl;
|
|
|
|
else if (i == 0 && keytimes[i] > 0.01)
|
|
|
|
kdWarning() << "animateMotion first keyTimes value not 0" << endl;
|
|
|
|
else
|
|
|
|
continue;
|
|
|
|
delete keytimes;
|
|
|
|
keytimes = NULL;
|
|
|
|
keytime_count = 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else if (name == "keySplines") {
|
|
|
|
splines = TQStringList::split (TQString (";"), val);
|
|
|
|
} else if (name == "calcMode") {
|
|
|
|
if (val == TQString::fromLatin1 ("discrete"))
|
|
|
|
calcMode = calc_discrete;
|
|
|
|
else if (val == TQString::fromLatin1 ("linear"))
|
|
|
|
calcMode = calc_linear;
|
|
|
|
else if (val == TQString::fromLatin1 ("paced"))
|
|
|
|
calcMode = calc_paced;
|
|
|
|
else if (val == TQString::fromLatin1 ("spline"))
|
|
|
|
calcMode = calc_spline;
|
|
|
|
} else
|
|
|
|
return AnimateGroupData::parseParam (name, val);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AnimateMotionData::getCoordinates (const TQString &coord, SizeType &x, SizeType &y) {
|
|
|
|
int p = coord.find (TQChar (','));
|
|
|
|
if (p > 0) {
|
|
|
|
x = coord.left (p).stripWhiteSpace ();
|
|
|
|
y = coord.mid (p + 1).stripWhiteSpace ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AnimateMotionData::setInterval () {
|
|
|
|
int cs = 10 * durTime ().offset;
|
|
|
|
if (keytime_count > interval + 1)
|
|
|
|
cs = (int) (cs * (keytimes[interval+1] - keytimes[interval]));
|
|
|
|
else if (values.size () > 1)
|
|
|
|
cs /= values.size () - 1;
|
|
|
|
if (cs < 0) {
|
|
|
|
kdWarning () << "animateMotion has no valid duration interval " <<
|
|
|
|
interval << endl;
|
|
|
|
propagateStop (true);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
steps = cs * 4 / 10; // 40 per sec
|
|
|
|
cur_step = 0;
|
|
|
|
cur_x = begin_x;
|
|
|
|
cur_y = begin_y;
|
|
|
|
delta_x = end_x;
|
|
|
|
delta_x -= begin_x;
|
|
|
|
delta_y = end_y;
|
|
|
|
delta_y -= begin_y;
|
|
|
|
switch (calcMode) {
|
|
|
|
case calc_paced: // FIXME
|
|
|
|
case calc_linear:
|
|
|
|
delta_x /= steps;
|
|
|
|
delta_y /= steps;
|
|
|
|
break;
|
|
|
|
case calc_spline:
|
|
|
|
if (splines.size () > interval) {
|
|
|
|
TQStringList kss = TQStringList::split (
|
|
|
|
TQString (" "), splines[interval]);
|
|
|
|
control_point[0] = control_point[1] = 0;
|
|
|
|
control_point[2] = control_point[3] = 1;
|
|
|
|
if (kss.size () == 4) {
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
control_point[i] = kss[i].toDouble();
|
|
|
|
if (control_point[i] < 0 || control_point[i] > 1) {
|
|
|
|
kdWarning () << "keySplines values not between 0-1"
|
|
|
|
<< endl;
|
|
|
|
control_point[i] = i > 1 ? 1 : 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
kdWarning () << "keySplines " << interval <<
|
|
|
|
" has not 4 values" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//kdDebug() << "setInterval " << steps << " " <<
|
|
|
|
// cur_x.size() << "," << cur_y.size() << "=>"
|
|
|
|
// << end_x.size() << "," << end_y.size() << " d:" <<
|
|
|
|
// delta_x.size() << "," << delta_y.size() << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateMotionData::started () {
|
|
|
|
//kdDebug () << "AnimateMotionData::started " << durTime ().durval << endl;
|
|
|
|
Element *target = convertNode <Element> (target_element);
|
|
|
|
if (!element || !checkTarget (target))
|
|
|
|
return;
|
|
|
|
if (anim_timer)
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
interval = 0;
|
|
|
|
if (change_from.isEmpty ()) {
|
|
|
|
if (values.size () > 1) {
|
|
|
|
getCoordinates (values[0], begin_x, begin_y);
|
|
|
|
getCoordinates (values[1], end_x, end_y);
|
|
|
|
} else {
|
|
|
|
CalculatedSizer sizes;
|
|
|
|
if (SMIL::id_node_region == target->id)
|
|
|
|
sizes = static_cast<SMIL::Region*>(target)->sizes;
|
|
|
|
else if (SMIL::id_node_first_mediatype <= target->id &&
|
|
|
|
SMIL::id_node_last_mediatype >= target->id)
|
|
|
|
sizes = static_cast<SMIL::MediaType*>(target)->sizes;
|
|
|
|
if (sizes.left.isSet ()) {
|
|
|
|
begin_x = sizes.left;
|
|
|
|
} else if (sizes.right.isSet() && sizes.width.isSet ()) {
|
|
|
|
begin_x = sizes.right;
|
|
|
|
begin_x -= sizes.width;
|
|
|
|
} else {
|
|
|
|
begin_x = "0";
|
|
|
|
}
|
|
|
|
if (sizes.top.isSet ()) {
|
|
|
|
begin_y = sizes.top;
|
|
|
|
} else if (sizes.bottom.isSet() && sizes.height.isSet ()) {
|
|
|
|
begin_y = sizes.bottom;
|
|
|
|
begin_y -= sizes.height;
|
|
|
|
} else {
|
|
|
|
begin_y = "0";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
getCoordinates (change_from, begin_x, begin_y);
|
|
|
|
}
|
|
|
|
if (!change_by.isEmpty ()) {
|
|
|
|
getCoordinates (change_by, delta_x, delta_y);
|
|
|
|
end_x = begin_x;
|
|
|
|
end_y = begin_y;
|
|
|
|
end_x += delta_x;
|
|
|
|
end_y += delta_y;
|
|
|
|
} else if (!change_to.isEmpty ()) {
|
|
|
|
getCoordinates (change_to, end_x, end_y);
|
|
|
|
}
|
|
|
|
if (!setInterval ())
|
|
|
|
return;
|
|
|
|
applyStep ();
|
|
|
|
anim_timer = element->document ()->setTimeout (element, 25, anim_timer_id);
|
|
|
|
AnimateGroupData::started ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateMotionData::stopped () {
|
|
|
|
if (element) {
|
|
|
|
if (anim_timer) // make sure timers are stopped
|
|
|
|
element->document ()->cancelTimer (anim_timer);
|
|
|
|
ASSERT (!anim_timer);
|
|
|
|
if (cur_step < steps && element->active () ||
|
|
|
|
(interval > 1 && calcMode == calc_discrete)) {
|
|
|
|
steps = 0;
|
|
|
|
if (cur_x.size () != end_x.size () ||
|
|
|
|
cur_y.size () != end_y.size ()) {
|
|
|
|
cur_x = end_x;
|
|
|
|
cur_y = end_y;
|
|
|
|
applyStep (); // we lost some steps ..
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
anim_timer = 0;
|
|
|
|
AnimateGroupData::stopped ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AnimateMotionData::applyStep () {
|
|
|
|
Node *target = target_element.ptr ();
|
|
|
|
if (!checkTarget (target))
|
|
|
|
return;
|
|
|
|
if (SMIL::id_node_region == target->id) {
|
|
|
|
SMIL::Region* r = static_cast <SMIL::Region*> (target);
|
|
|
|
if (r->surface ()) {
|
|
|
|
r->sizes.move (cur_x, cur_y);
|
|
|
|
r->boundsUpdate ();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
SMIL::MediaType *mt = static_cast <SMIL::MediaType *> (target);
|
|
|
|
if (mt->surface ()) {
|
|
|
|
mt->sizes.move (cur_x, cur_y);
|
|
|
|
mt->boundsUpdate ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool AnimateMotionData::timerTick () {
|
|
|
|
if (!anim_timer) {
|
|
|
|
kdError () << "spurious animateMotion timer tick" << endl;
|
|
|
|
} else if (cur_step++ < steps) {
|
|
|
|
switch (calcMode) {
|
|
|
|
case calc_paced: // FIXME
|
|
|
|
case calc_linear:
|
|
|
|
cur_x += delta_x;
|
|
|
|
cur_y += delta_y;
|
|
|
|
break;
|
|
|
|
case calc_spline: {
|
|
|
|
Point2D ps[4] = {
|
|
|
|
{ 0, 0 },
|
|
|
|
{ control_point[0], control_point[1] },
|
|
|
|
{ control_point[2], control_point[3] },
|
|
|
|
{ 1, 1 }
|
|
|
|
};
|
|
|
|
Point2D p = PointOnCubicBezier (ps, 1.0 * cur_step / steps);
|
|
|
|
cur_x = delta_x;
|
|
|
|
cur_y = delta_y;
|
|
|
|
cur_x *= p.y;
|
|
|
|
cur_y *= p.y;
|
|
|
|
cur_x += begin_x;
|
|
|
|
cur_y += begin_y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case calc_discrete:
|
|
|
|
return true; // very sub-optimal timer
|
|
|
|
}
|
|
|
|
applyStep ();
|
|
|
|
return true;
|
|
|
|
} else if (values.size () > ++interval + 1) {
|
|
|
|
getCoordinates (values[interval], begin_x, begin_y);
|
|
|
|
getCoordinates (values[interval+1], end_x, end_y);
|
|
|
|
if (setInterval ()) {
|
|
|
|
applyStep ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
anim_timer = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static NodePtr findExternalTree (NodePtr mrl) {
|
|
|
|
for (NodePtr c = mrl->firstChild (); c; c = c->nextSibling ()) {
|
|
|
|
Mrl * m = c->mrl ();
|
|
|
|
if (m && m->opener == mrl)
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT MediaTypeRuntime::MediaTypeRuntime (NodePtr e)
|
|
|
|
: Runtime (e) {}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT MediaTypeRuntime::~MediaTypeRuntime () {
|
|
|
|
killWGet ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* re-implement for pending TDEIO::Job operations
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void KMPlayer::MediaTypeRuntime::reset () {
|
|
|
|
clear ();
|
|
|
|
postpone_lock = 0L;
|
|
|
|
Runtime::reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* will request a repaint of attached region
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void MediaTypeRuntime::stopped () {
|
|
|
|
clipStop ();
|
|
|
|
document_postponed = 0L;
|
|
|
|
Node * e = element.ptr ();
|
|
|
|
if (e) {
|
|
|
|
for (NodePtr n = e->firstChild (); n; n = n->nextSibling ())
|
|
|
|
if (n->unfinished ()) // finish child documents
|
|
|
|
n->finish ();
|
|
|
|
}
|
|
|
|
Runtime::stopped ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void MediaTypeRuntime::clipStart () {
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
SMIL::RegionBase *r =mt ? convertNode<SMIL::RegionBase>(mt->region_node):0L;
|
|
|
|
if (r && r->surface ())
|
|
|
|
for (NodePtr n = mt->firstChild (); n; n = n->nextSibling ())
|
|
|
|
if ((n->mrl () && n->mrl ()->opener.ptr () == mt) ||
|
|
|
|
n->id == SMIL::id_node_smil ||
|
|
|
|
n->id == RP::id_node_imfl) {
|
|
|
|
n->activate ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void MediaTypeRuntime::clipStop () {
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (mt) {
|
|
|
|
mt->resetSurface ();
|
|
|
|
if (mt->external_tree && mt->external_tree->active ())
|
|
|
|
mt->external_tree->deactivate ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void MediaTypeRuntime::postpone (bool) {
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT AudioVideoData::AudioVideoData (NodePtr e)
|
|
|
|
: MediaTypeRuntime (e) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool AudioVideoData::isAudioVideo () {
|
|
|
|
return timingstate == timings_started;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* reimplement for request backend to play audio/video
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void AudioVideoData::started () {
|
|
|
|
if (element && !element->mrl ()->resolved) {
|
|
|
|
element->defer ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (0 == durTime ().offset && dur_media == endTime ().durval)
|
|
|
|
durTime ().durval = dur_media; // duration of clip
|
|
|
|
MediaTypeRuntime::started ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void setSmilLinkNode (NodePtr n, NodePtr link) {
|
|
|
|
// this works only because we can only play one at a time FIXME
|
|
|
|
SMIL::Smil * s = SMIL::Smil::findSmilNode (n.ptr ());
|
|
|
|
if (s && (link || s->current_av_media_type == n)) // only reset ones own
|
|
|
|
s->current_av_media_type = link;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AudioVideoData::clipStart () {
|
|
|
|
NodePtr element_protect = element; // note element is weak
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
PlayListNotify * n = mt ? mt->document ()->notify_listener : 0L;
|
|
|
|
//kdDebug() << "AudioVideoData::clipStart " << mt->resolved << endl;
|
|
|
|
if (n && mt->region_node && !mt->external_tree && !mt->src.isEmpty()) {
|
|
|
|
setSmilLinkNode (element, element);
|
|
|
|
mt->repeat = repeat_count == dur_infinite ? 9998 : repeat_count;
|
|
|
|
repeat_count = 0;
|
|
|
|
n->requestPlayURL (mt);
|
|
|
|
document_postponed = mt->document()->connectTo(mt, event_postponed);
|
|
|
|
}
|
|
|
|
MediaTypeRuntime::clipStart ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AudioVideoData::clipStop () {
|
|
|
|
if (durTime ().durval == dur_media)
|
|
|
|
durTime ().durval = dur_timer;//reset to make this finish
|
|
|
|
MediaTypeRuntime::clipStop ();
|
|
|
|
setSmilLinkNode (element, 0L);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
bool AudioVideoData::parseParam(const TrieString &name, const TQString &val) {
|
|
|
|
//kdDebug () << "AudioVideoData::parseParam " << name << "=" << val << endl;
|
|
|
|
if (name == StringPool::attr_src) {
|
|
|
|
NodePtr element_protect = element; // note element is weak
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (mt) {
|
|
|
|
if (!mt->resolved || mt->src != val) {
|
|
|
|
if (mt->external_tree)
|
|
|
|
mt->removeChild (mt->external_tree);
|
|
|
|
mt->src = val;
|
|
|
|
mt->resolved = mt->document ()->notify_listener->resolveURL (element);
|
|
|
|
}
|
|
|
|
if (timingstate == timings_started && mt->resolved)
|
|
|
|
clipStart ();
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
return MediaTypeRuntime::parseParam (name, val);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void AudioVideoData::postpone (bool b) {
|
|
|
|
kdDebug () << "AudioVideoData::postpone " << b << endl;
|
|
|
|
if (element->unfinished () && b)
|
|
|
|
element->setState (Node::state_deferred);
|
|
|
|
else if (element->state == Node::state_deferred && !b)
|
|
|
|
element->setState (Node::state_began);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT MouseListeners::MouseListeners () :
|
|
|
|
m_ActionListeners (new NodeRefList),
|
|
|
|
m_OutOfBoundsListeners (new NodeRefList),
|
|
|
|
m_InBoundsListeners (new NodeRefList) {}
|
|
|
|
|
|
|
|
NodeRefListPtr MouseListeners::listeners (unsigned int eid) {
|
|
|
|
switch (eid) {
|
|
|
|
case event_activated:
|
|
|
|
return m_ActionListeners;
|
|
|
|
case event_inbounds:
|
|
|
|
return m_InBoundsListeners;
|
|
|
|
case event_outbounds:
|
|
|
|
return m_OutOfBoundsListeners;
|
|
|
|
}
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static Element * fromScheduleGroup (NodePtr & d, const TQString & tag) {
|
|
|
|
const char * ctag = tag.ascii ();
|
|
|
|
if (!strcmp (ctag, "par"))
|
|
|
|
return new SMIL::Par (d);
|
|
|
|
else if (!strcmp (ctag, "seq"))
|
|
|
|
return new SMIL::Seq (d);
|
|
|
|
else if (!strcmp (ctag, "excl"))
|
|
|
|
return new SMIL::Excl (d);
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Element * fromParamGroup (NodePtr & d, const TQString & tag) {
|
|
|
|
const char * ctag = tag.ascii ();
|
|
|
|
if (!strcmp (ctag, "param"))
|
|
|
|
return new SMIL::Param (d);
|
|
|
|
else if (!strcmp (ctag, "area") || !strcmp (ctag, "anchor"))
|
|
|
|
return new SMIL::Area (d, tag);
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Element * fromAnimateGroup (NodePtr & d, const TQString & tag) {
|
|
|
|
const char * ctag = tag.ascii ();
|
|
|
|
if (!strcmp (ctag, "set"))
|
|
|
|
return new SMIL::Set (d);
|
|
|
|
else if (!strcmp (ctag, "animate"))
|
|
|
|
return new SMIL::Animate (d);
|
|
|
|
else if (!strcmp (ctag, "animateMotion"))
|
|
|
|
return new SMIL::AnimateMotion (d);
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Element * fromMediaContentGroup (NodePtr & d, const TQString & tag) {
|
|
|
|
const char * taglatin = tag.latin1 ();
|
|
|
|
if (!strcmp (taglatin, "video") || !strcmp (taglatin, "audio"))
|
|
|
|
return new SMIL::AVMediaType (d, tag);
|
|
|
|
else if (!strcmp (taglatin, "img"))
|
|
|
|
return new SMIL::ImageMediaType (d);
|
|
|
|
else if (!strcmp (taglatin, "text"))
|
|
|
|
return new SMIL::TextMediaType (d);
|
|
|
|
else if (!strcmp (taglatin, "ref"))
|
|
|
|
return new SMIL::RefMediaType (d);
|
|
|
|
else if (!strcmp (taglatin, "brush"))
|
|
|
|
return new SMIL::Brush (d);
|
|
|
|
else if (!strcmp (taglatin, "a"))
|
|
|
|
return new SMIL::Anchor (d);
|
|
|
|
// animation, textstream
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Element * fromContentControlGroup (NodePtr & d, const TQString & tag) {
|
|
|
|
if (!strcmp (tag.latin1 (), "switch"))
|
|
|
|
return new SMIL::Switch (d);
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::Smil::childFromTag (const TQString & tag) {
|
|
|
|
const char * ctag = tag.ascii ();
|
|
|
|
if (!strcmp (ctag, "body"))
|
|
|
|
return new SMIL::Body (m_doc);
|
|
|
|
else if (!strcmp (ctag, "head"))
|
|
|
|
return new SMIL::Head (m_doc);
|
|
|
|
return NodePtr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Smil::activate () {
|
|
|
|
//kdDebug () << "Smil::activate" << endl;
|
|
|
|
current_av_media_type = NodePtr ();
|
|
|
|
resolved = true;
|
|
|
|
SMIL::Layout * layout = convertNode <SMIL::Layout> (layout_node);
|
|
|
|
if (layout && layout->region_surface) {
|
|
|
|
kdError() << "Layout already has a surface" << endl;
|
|
|
|
}
|
|
|
|
if (layout)
|
|
|
|
Element::activate ();
|
|
|
|
else
|
|
|
|
Element::deactivate(); // some unfortunate reset in parent doc
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Smil::deactivate () {
|
|
|
|
if (layout_node)
|
|
|
|
convertNode <SMIL::Layout> (layout_node)->repaint ();
|
|
|
|
if (layout_node)
|
|
|
|
convertNode <SMIL::Layout> (layout_node)->region_surface = NULL;
|
|
|
|
Mrl::getSurface(0L);
|
|
|
|
Mrl::deactivate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::Smil::handleEvent (EventPtr event) {
|
|
|
|
return layout_node ? layout_node->handleEvent (event) : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Smil::closed () {
|
|
|
|
NodePtr head;
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (e->id == id_node_head) {
|
|
|
|
head = e;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!head) {
|
|
|
|
SMIL::Head * h = new SMIL::Head (m_doc);
|
|
|
|
insertBefore (h, firstChild ());
|
|
|
|
h->setAuxiliaryNode (true);
|
|
|
|
h->closed ();
|
|
|
|
head = h;
|
|
|
|
}
|
|
|
|
for (NodePtr e = head->firstChild (); e; e = e->nextSibling ()) {
|
|
|
|
if (e->id == id_node_layout) {
|
|
|
|
layout_node = e;
|
|
|
|
} else if (e->id == id_node_title) {
|
|
|
|
TQString str = e->innerText ();
|
|
|
|
pretty_name = str.left (str.find (TQChar ('\n')));
|
|
|
|
} else if (e->id == id_node_meta) {
|
|
|
|
Element * elm = convertNode <Element> (e);
|
|
|
|
const TQString name = elm->getAttribute (StringPool::attr_name);
|
|
|
|
if (name == TQString::fromLatin1 ("title"))
|
|
|
|
pretty_name = elm->getAttribute ("content");
|
|
|
|
else if (name == TQString::fromLatin1 ("base"))
|
|
|
|
src = elm->getAttribute ("content");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!layout_node) {
|
|
|
|
kdError () << "no <root-layout>" << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Smil::childDone (NodePtr child) {
|
|
|
|
if (unfinished ()) {
|
|
|
|
if (child->nextSibling ())
|
|
|
|
child->nextSibling ()->activate ();
|
|
|
|
else {
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (e->active ())
|
|
|
|
e->deactivate ();
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Mrl * SMIL::Smil::linkNode () {
|
|
|
|
return current_av_media_type ? current_av_media_type->mrl () : this;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::Smil::expose () const {
|
|
|
|
return !pretty_name.isEmpty () || //return false if no title and only one
|
|
|
|
previousSibling () || nextSibling ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Smil::accept (Visitor * v) {
|
|
|
|
if (active () && layout_node)
|
|
|
|
layout_node->accept( v );
|
|
|
|
}
|
|
|
|
|
|
|
|
void SMIL::Smil::jump (const TQString & id) {
|
|
|
|
NodePtr n = document ()->getElementById (this, id, false);
|
|
|
|
if (n) {
|
|
|
|
if (n->unfinished ())
|
|
|
|
kdDebug() << "Smil::jump node is unfinished " << id << endl;
|
|
|
|
else {
|
|
|
|
for (NodePtr p = n; p; p = p->parentNode ()) {
|
|
|
|
if (p->unfinished () &&
|
|
|
|
p->id >= id_node_first_group &&
|
|
|
|
p->id <= id_node_last_group) {
|
|
|
|
convertNode <GroupBase> (p)->setJumpNode (n);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (n->id == id_node_body || n->id == id_node_smil) {
|
|
|
|
kdError() << "Smil::jump node passed body for " <<id<< endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SMIL::Smil * SMIL::Smil::findSmilNode (Node * node) {
|
|
|
|
for (Node * e = node; e; e = e->parentNode ().ptr ())
|
|
|
|
if (e->id == SMIL::id_node_smil)
|
|
|
|
return static_cast <SMIL::Smil *> (e);
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static void headChildDone (NodePtr node, NodePtr child) {
|
|
|
|
if (node->unfinished ()) {
|
|
|
|
if (child->nextSibling ())
|
|
|
|
child->nextSibling ()->activate ();
|
|
|
|
else
|
|
|
|
node->finish (); // we're done
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::Head::childFromTag (const TQString & tag) {
|
|
|
|
const char * ctag = tag.ascii ();
|
|
|
|
if (!strcmp (ctag, "layout"))
|
|
|
|
return new SMIL::Layout (m_doc);
|
|
|
|
else if (!strcmp (ctag, "title"))
|
|
|
|
return new DarkNode (m_doc, tag, id_node_title);
|
|
|
|
else if (!strcmp (ctag, "meta"))
|
|
|
|
return new DarkNode (m_doc, tag, id_node_meta);
|
|
|
|
else if (!strcmp (ctag, "transition"))
|
|
|
|
return new SMIL::Transition (m_doc);
|
|
|
|
return NodePtr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::Head::expose () const {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Head::closed () {
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (e->id == id_node_layout)
|
|
|
|
return;
|
|
|
|
SMIL::Layout * layout = new SMIL::Layout (m_doc);
|
|
|
|
appendChild (layout);
|
|
|
|
layout->setAuxiliaryNode (true);
|
|
|
|
layout->closed (); // add root-layout and a region
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Head::childDone (NodePtr child) {
|
|
|
|
headChildDone (this, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::Layout::Layout (NodePtr & d)
|
|
|
|
: RegionBase (d, id_node_layout) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::Layout::childFromTag (const TQString & tag) {
|
|
|
|
const char * ctag = tag.ascii ();
|
|
|
|
if (!strcmp (ctag, "root-layout")) {
|
|
|
|
NodePtr e = new SMIL::RootLayout (m_doc);
|
|
|
|
rootLayout = e;
|
|
|
|
return e;
|
|
|
|
} else if (!strcmp (ctag, "region"))
|
|
|
|
return new SMIL::Region (m_doc);
|
|
|
|
else if (!strcmp (ctag, "regPoint"))
|
|
|
|
return new SMIL::RegPoint (m_doc);
|
|
|
|
return NodePtr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Layout::closed () {
|
|
|
|
SMIL::RegionBase * rl = convertNode <SMIL::RootLayout> (rootLayout);
|
|
|
|
bool has_root (rl);
|
|
|
|
if (!has_root) { // just add one if none there
|
|
|
|
rl = new SMIL::RootLayout (m_doc);
|
|
|
|
NodePtr sr = rl; // protect against destruction
|
|
|
|
rl->setAuxiliaryNode (true);
|
|
|
|
rootLayout = rl;
|
|
|
|
int w_root =0, h_root = 0, reg_count = 0;
|
|
|
|
for (NodePtr n = firstChild (); n; n = n->nextSibling ()) {
|
|
|
|
if (n->id == id_node_region) {
|
|
|
|
SMIL::Region * rb =convertNode <SMIL::Region> (n);
|
|
|
|
rb->init ();
|
|
|
|
rb->calculateBounds (0, 0);
|
|
|
|
if (int (rb->x + rb->w) > w_root)
|
|
|
|
w_root = rb->x + rb->w;
|
|
|
|
if (int (rb->y + rb->h) > h_root)
|
|
|
|
h_root = rb->y + rb->h;
|
|
|
|
reg_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!reg_count) {
|
|
|
|
w_root = 320; h_root = 240; // have something to start with
|
|
|
|
SMIL::Region * r = new SMIL::Region (m_doc);
|
|
|
|
appendChild (r);
|
|
|
|
r->setAuxiliaryNode (true);
|
|
|
|
}
|
|
|
|
rl->setAttribute(StringPool::attr_width, TQString::number(w_root));
|
|
|
|
rl->setAttribute(StringPool::attr_height,TQString::number(h_root));
|
|
|
|
insertBefore (sr, firstChild ());
|
|
|
|
} else {
|
|
|
|
if (childNodes ()->length () < 2) { // only a root-layout
|
|
|
|
SMIL::Region * r = new SMIL::Region (m_doc);
|
|
|
|
appendChild (r);
|
|
|
|
r->setAuxiliaryNode (true);
|
|
|
|
}
|
|
|
|
Smil *s = Smil::findSmilNode (this);
|
|
|
|
if (s) {
|
|
|
|
s->width = rl->getAttribute(StringPool::attr_width).toDouble ();
|
|
|
|
s->height = rl->getAttribute(StringPool::attr_height).toDouble();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Layout::activate () {
|
|
|
|
//kdDebug () << "SMIL::Layout::activate" << endl;
|
|
|
|
RegionBase::activate ();
|
|
|
|
if (surface ()) {
|
|
|
|
updateDimensions ();
|
|
|
|
repaint ();
|
|
|
|
}
|
|
|
|
finish (); // proceed and allow 'head' to finish
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Layout::updateDimensions () {
|
|
|
|
RegionBase * rb = static_cast <RegionBase *> (rootLayout.ptr ());
|
|
|
|
x = y = 0;
|
|
|
|
w = rb->sizes.width.size ();
|
|
|
|
h = rb->sizes.height.size ();
|
|
|
|
//kdDebug () << "Layout::updateDimensions " << w << "," << h <<endl;
|
|
|
|
SMIL::RegionBase::updateDimensions ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Surface *SMIL::Layout::surface () {
|
|
|
|
if (!region_surface) {
|
|
|
|
SMIL::Smil * s = Smil::findSmilNode (this);
|
|
|
|
if (s) {
|
|
|
|
SMIL::RegionBase *rl = convertNode <SMIL::RootLayout> (rootLayout);
|
|
|
|
region_surface = s->getSurface (s);
|
|
|
|
w = s->width;
|
|
|
|
h = s->height;
|
|
|
|
if (region_surface) {
|
|
|
|
SRect rect = region_surface->bounds;
|
|
|
|
if (rl && auxiliaryNode ()) {
|
|
|
|
w = rect.width ();
|
|
|
|
h = rect.height ();
|
|
|
|
rl->setAttribute (StringPool::attr_width, TQString::number ((int)w));
|
|
|
|
rl->setAttribute (StringPool::attr_height, TQString::number ((int)h));
|
|
|
|
rl->setParam (StringPool::attr_width, TQString::number((int)w));
|
|
|
|
rl->setParam (StringPool::attr_height,TQString::number((int)h));
|
|
|
|
} else if (region_surface && w > 0 && h > 0) {
|
|
|
|
updateDimensions ();
|
|
|
|
}
|
|
|
|
//kdDebug() << "Layout::surface bounds " << rect.width () << "x" << rect.height () << " w:" << w << " h:" << h << " xs:" << region_surface->xscale << " ys:" << region_surface->yscale << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return region_surface.ptr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Layout::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::RegionBase::RegionBase (NodePtr & d, short id)
|
|
|
|
: Element (d, id), x (0), y (0), w (0), h (0),
|
|
|
|
z_order (1), background_color (0)
|
|
|
|
{}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::RegionBase::~RegionBase () {
|
|
|
|
if (region_surface)
|
|
|
|
region_surface->remove ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::activate () {
|
|
|
|
show_background = ShowAlways;
|
|
|
|
init ();
|
|
|
|
setState (state_activated);
|
|
|
|
for (NodePtr r = firstChild (); r; r = r->nextSibling ())
|
|
|
|
if (r->id == id_node_region || r->id == id_node_root_layout)
|
|
|
|
r->activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::childDone (NodePtr child) {
|
|
|
|
headChildDone (this, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::deactivate () {
|
|
|
|
background_color = 0;
|
|
|
|
background_image.truncate (0);
|
|
|
|
if (region_surface)
|
|
|
|
region_surface->background_color = 0;
|
|
|
|
cached_img.setUrl (TQString ());
|
|
|
|
postpone_lock = NULL;
|
|
|
|
killWGet ();
|
|
|
|
sizes.resetSizes ();
|
|
|
|
Element::deactivate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::remoteReady (TQByteArray & data) {
|
|
|
|
TQImage *pix = new TQImage (data);
|
|
|
|
if (!pix->isNull ()) {
|
|
|
|
cached_img.data->image = pix;
|
|
|
|
if (region_surface)
|
|
|
|
region_surface->remove (); // FIXME: only surface
|
|
|
|
} else {
|
|
|
|
delete pix;
|
|
|
|
}
|
|
|
|
postpone_lock = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::repaint () {
|
|
|
|
if (surface ())
|
|
|
|
region_surface->repaint (SRect (0, 0, w, h));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::repaint (const SRect & rect) {
|
|
|
|
if (surface ())
|
|
|
|
region_surface->repaint (SRect (0, 0, w, h).intersect (rect));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::updateDimensions () {
|
|
|
|
if (surface () && active ())
|
|
|
|
for (NodePtr r = firstChild (); r; r = r->nextSibling ())
|
|
|
|
if (r->id == id_node_region) {
|
|
|
|
SMIL::Region * cr = static_cast <SMIL::Region *> (r.ptr ());
|
|
|
|
cr->calculateBounds (w, h);
|
|
|
|
cr->updateDimensions ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RegionBase::boundsUpdate () {
|
|
|
|
// if there is a region_surface and it's moved, do a limit repaint
|
|
|
|
NodePtr p = parentNode ();
|
|
|
|
if (p && (p->id==SMIL::id_node_region || p->id==SMIL::id_node_layout) &&
|
|
|
|
region_surface) {
|
|
|
|
RegionBase *pr = convertNode <SMIL::RegionBase> (p);
|
|
|
|
SRect old_bounds = region_surface->bounds;
|
|
|
|
w = 0; h = 0;
|
|
|
|
sizes.calcSizes (this, pr->w, pr->h, x, y, w, h);
|
|
|
|
region_surface->bounds = SRect (x, y, w, h);
|
|
|
|
pr->repaint (region_surface->bounds.unite (old_bounds));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Surface *SMIL::RegionBase::surface () {
|
|
|
|
if (!region_surface) {
|
|
|
|
Node *n = parentNode ().ptr ();
|
|
|
|
if (n &&
|
|
|
|
(SMIL::id_node_region == n->id ||
|
|
|
|
SMIL::id_node_layout == n->id)) {
|
|
|
|
Surface *ps = static_cast <SMIL::Region *> (n)->surface ();
|
|
|
|
if (ps) {
|
|
|
|
region_surface = ps->createSurface (this, SRect (x, y, w, h));
|
|
|
|
region_surface->background_color = background_color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return region_surface.ptr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::RegionBase::parseParam (const TrieString & name, const TQString & val) {
|
|
|
|
//kdDebug () << "RegionBase::parseParam " << getAttribute ("id") << " " << name << "=" << val << " active:" << active() << endl;
|
|
|
|
bool need_repaint = false;
|
|
|
|
SRect rect = SRect (x, y, w, h);
|
|
|
|
bool dim_changed;
|
|
|
|
if (name == "background-color" || name == "backgroundColor") {
|
|
|
|
if (val.isEmpty ())
|
|
|
|
background_color = 0;
|
|
|
|
else
|
|
|
|
background_color = 0xff000000 | TQColor (val).rgb ();
|
|
|
|
if (region_surface || (active () && surface ()))
|
|
|
|
region_surface->background_color = background_color;
|
|
|
|
need_repaint = true;
|
|
|
|
} else if (name == "z-index") {
|
|
|
|
z_order = val.toInt ();
|
|
|
|
need_repaint = true;
|
|
|
|
} else if (sizes.setSizeParam (name, val, dim_changed)) {
|
|
|
|
if (active ()) {
|
|
|
|
if (region_surface) {
|
|
|
|
if (dim_changed) {
|
|
|
|
region_surface->remove ();
|
|
|
|
} else {
|
|
|
|
boundsUpdate ();
|
|
|
|
return; // smart update of old bounds to new moved one
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NodePtr p = parentNode ();
|
|
|
|
if (p &&(p->id==SMIL::id_node_region ||p->id==SMIL::id_node_layout))
|
|
|
|
convertNode <SMIL::RegionBase> (p)->updateDimensions ();
|
|
|
|
rect = rect.unite (SRect (x, y, w, h));
|
|
|
|
need_repaint = true;
|
|
|
|
}
|
|
|
|
} else if (name == "showBackground") {
|
|
|
|
if (val == "whenActive")
|
|
|
|
show_background = ShowWhenActive;
|
|
|
|
else
|
|
|
|
show_background = ShowAlways;
|
|
|
|
need_repaint = true;
|
|
|
|
} else if (name == "backgroundImage") {
|
|
|
|
background_image = val;
|
|
|
|
Smil * s = SMIL::Smil::findSmilNode (this);
|
|
|
|
if (s) {
|
|
|
|
killWGet ();
|
|
|
|
need_repaint = !cached_img.isEmpty ();
|
|
|
|
Mrl *mrl = s->parentNode () ? s->parentNode ()->mrl () : NULL;
|
|
|
|
TQString url = mrl ? KURL (mrl->absolutePath (), val).url () : val;
|
|
|
|
cached_img.setUrl (url);
|
|
|
|
if (cached_img.isEmpty ()) {
|
|
|
|
postpone_lock = document ()->postpone ();
|
|
|
|
wget (url);
|
|
|
|
} else {
|
|
|
|
need_repaint = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (need_repaint && active () && surface() && region_surface->parentNode ())
|
|
|
|
region_surface->parentNode ()->repaint (rect);
|
|
|
|
Element::parseParam (name, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::Region::Region (NodePtr & d)
|
|
|
|
: RegionBase (d, id_node_region),
|
|
|
|
has_mouse (false),
|
|
|
|
m_AttachedMediaTypes (new NodeRefList) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::Region::childFromTag (const TQString & tag) {
|
|
|
|
if (!strcmp (tag.latin1 (), "region"))
|
|
|
|
return new SMIL::Region (m_doc);
|
|
|
|
return NodePtr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* calculates dimensions of this regions with _w and _h as width and height
|
|
|
|
* of parent Region (representing 100%)
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::Region::calculateBounds (Single pw, Single ph) {
|
|
|
|
Single x1 (x), y1 (y), w1 (w), h1 (h);
|
|
|
|
sizes.calcSizes (this, pw, ph, x, y, w, h);
|
|
|
|
if (surface ())
|
|
|
|
region_surface->bounds = SRect (x, y, w, h);
|
|
|
|
//kdDebug () << "Region::calculateBounds parent:" << pw << "x" << ph << " this:" << x << "," << y << " " << w << "x" << h << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
NodeRefListPtr SMIL::Region::listeners (unsigned int eid) {
|
|
|
|
NodeRefListPtr l = mouse_listeners.listeners (eid);
|
|
|
|
if (l)
|
|
|
|
return l;
|
|
|
|
switch (eid) {
|
|
|
|
case mediatype_attached:
|
|
|
|
return m_AttachedMediaTypes;
|
|
|
|
}
|
|
|
|
return RegionBase::listeners (eid);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Region::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::RegPoint::parseParam (const TrieString & p, const TQString & v) {
|
|
|
|
bool b;
|
|
|
|
sizes.setSizeParam (p, v, b); // TODO: if dynamic, make sure to repaint
|
|
|
|
Element::parseParam (p, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static struct TransTypeInfo {
|
|
|
|
const char *name;
|
|
|
|
SMIL::Transition::TransType type;
|
|
|
|
short sub_types;
|
|
|
|
SMIL::Transition::TransSubType sub_type[8];
|
|
|
|
} transition_type_info[] = {
|
|
|
|
#include "transitions.txt"
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct SubTransTypeInfo {
|
|
|
|
const char *name;
|
|
|
|
SMIL::Transition::TransSubType sub_type;
|
|
|
|
} sub_transition_type_info[] = {
|
|
|
|
#include "subtrans.txt"
|
|
|
|
};
|
|
|
|
|
|
|
|
static TransTypeInfo *transInfoFromString (const char *t) {
|
|
|
|
// TODO binary search
|
|
|
|
for (int i = 0; transition_type_info[i].name; ++i)
|
|
|
|
if (!strcmp (t, transition_type_info[i].name))
|
|
|
|
return transition_type_info + i;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
SMIL::Transition::TransSubType subTransInfoFromString (const char *s) {
|
|
|
|
for (int i = 0; sub_transition_type_info[i].name; ++i)
|
|
|
|
if (!strcmp (s, sub_transition_type_info[i].name))
|
|
|
|
return sub_transition_type_info[i].sub_type;
|
|
|
|
return SMIL::Transition::SubTransTypeNone;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::Transition::Transition (NodePtr & d)
|
|
|
|
: Element (d, id_node_transition),
|
|
|
|
type_info (NULL), direction (dir_forward), dur (10), fade_color (0) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Transition::activate () {
|
|
|
|
type = TransTypeNone;
|
|
|
|
sub_type = SubTransTypeNone;
|
|
|
|
start_progress = 0.0;
|
|
|
|
end_progress = 1.0;
|
|
|
|
type_info = NULL;
|
|
|
|
init ();
|
|
|
|
Element::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::Transition::parseParam (const TrieString & para, const TQString & val) {
|
|
|
|
if (para == StringPool::attr_type) {
|
|
|
|
type_info = transInfoFromString (val.ascii ());
|
|
|
|
if (type_info) {
|
|
|
|
type = type_info->type;
|
|
|
|
if (SubTransTypeNone != sub_type) {
|
|
|
|
for (int i = 0; i < type_info->sub_types; ++i)
|
|
|
|
if (type_info->sub_type[i] == sub_type)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (type_info->sub_types > 0)
|
|
|
|
sub_type = type_info->sub_type[0];
|
|
|
|
}
|
|
|
|
} else if (para == StringPool::attr_dur) {
|
|
|
|
parseTime (val, dur);
|
|
|
|
} else if (para == "subtype") {
|
|
|
|
sub_type = subTransInfoFromString (val.ascii ());
|
|
|
|
if (type_info) {
|
|
|
|
if (SubTransTypeNone != sub_type) {
|
|
|
|
for (int i = 0; i < type_info->sub_types; ++i)
|
|
|
|
if (type_info->sub_type[i] == sub_type)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (type_info->sub_types > 0)
|
|
|
|
sub_type = type_info->sub_type[0];
|
|
|
|
}
|
|
|
|
} else if (para == "fadeColor") {
|
|
|
|
fade_color = TQColor (getAttribute (val)).rgb ();
|
|
|
|
} else if (para == "direction") {
|
|
|
|
direction = val == "reverse" ? dir_reverse : dir_forward;
|
|
|
|
} else if (para == "startProgress") {
|
|
|
|
start_progress = val.toDouble();
|
|
|
|
if (start_progress < 0.0)
|
|
|
|
start_progress = 0.0;
|
|
|
|
else if (start_progress > 1.0)
|
|
|
|
start_progress = 1.0;
|
|
|
|
} else if (para == "endProgress") {
|
|
|
|
end_progress = val.toDouble();
|
|
|
|
if (end_progress < start_progress)
|
|
|
|
end_progress = start_progress;
|
|
|
|
else if (end_progress > 1.0)
|
|
|
|
end_progress = 1.0;
|
|
|
|
} else {
|
|
|
|
Element::parseParam (para, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::Transition::supported () {
|
|
|
|
switch (type) {
|
|
|
|
case Fade:
|
|
|
|
case BarWipe:
|
|
|
|
case BowTieWipe:
|
|
|
|
case PushWipe:
|
|
|
|
case IrisWipe:
|
|
|
|
case ClockWipe:
|
|
|
|
case EllipseWipe:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::TimedMrl::TimedMrl (NodePtr & d, short id)
|
|
|
|
: Mrl (d, id),
|
|
|
|
fill_active (fill_auto),
|
|
|
|
m_StartListeners (new NodeRefList),
|
|
|
|
m_StartedListeners (new NodeRefList),
|
|
|
|
m_StoppedListeners (new NodeRefList),
|
|
|
|
m_runtime (0L) {}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::TimedMrl::~TimedMrl () {
|
|
|
|
delete m_runtime;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::closed () {
|
|
|
|
pretty_name = getAttribute (StringPool::attr_title);
|
|
|
|
Mrl::closed ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::init () {
|
|
|
|
runtime ()->reset ();
|
|
|
|
begin_time = finish_time = 0;
|
|
|
|
fill = fill_default;
|
|
|
|
fill_def = fill_inherit;
|
|
|
|
fill_active = getDefaultFill (this);
|
|
|
|
Mrl::init ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::activate () {
|
|
|
|
//kdDebug () << "SMIL::TimedMrl(" << nodeName() << ")::activate" << endl;
|
|
|
|
Runtime * rt = runtime ();
|
|
|
|
init ();
|
|
|
|
setState (state_activated);
|
|
|
|
if (rt == m_runtime) // Runtime might already be dead
|
|
|
|
rt->begin ();
|
|
|
|
else
|
|
|
|
deactivate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::begin () {
|
|
|
|
begin_time = document ()->last_event_time;
|
|
|
|
Element::begin ();
|
|
|
|
runtime ()->propagateStop (false); //see whether this node has a livetime or not
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::deactivate () {
|
|
|
|
//kdDebug () << "SMIL::TimedMrl(" << nodeName() << ")::deactivate" << endl;
|
|
|
|
if (unfinished ())
|
|
|
|
finish ();
|
|
|
|
if (m_runtime) {
|
|
|
|
m_runtime->reset ();
|
|
|
|
delete m_runtime;
|
|
|
|
m_runtime = 0L;
|
|
|
|
}
|
|
|
|
Mrl::deactivate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::finish () {
|
|
|
|
if (m_runtime &&
|
|
|
|
(m_runtime->state () == Runtime::timings_started ||
|
|
|
|
m_runtime->state () == Runtime::timings_began)) {
|
|
|
|
runtime ()->propagateStop (true); // reschedule through Runtime::stopped
|
|
|
|
} else {
|
|
|
|
finish_time = document ()->last_event_time;
|
|
|
|
Mrl::finish ();
|
|
|
|
propagateEvent (new Event (event_stopped));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::reset () {
|
|
|
|
//kdDebug () << "SMIL::TimedMrl::reset " << endl;
|
|
|
|
Mrl::reset ();
|
|
|
|
delete m_runtime;
|
|
|
|
m_runtime = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::childBegan (NodePtr) {
|
|
|
|
if (state != state_began)
|
|
|
|
begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Re-implement, but keeping sequential behaviour.
|
|
|
|
* Bail out if Runtime is running. In case of dur_media, give Runtime
|
|
|
|
* a hand with calling propagateStop(true)
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void SMIL::TimedMrl::childDone (NodePtr c) {
|
|
|
|
if (!active ())
|
|
|
|
return; // forced reset
|
|
|
|
if (c->nextSibling ())
|
|
|
|
c->nextSibling ()->activate ();
|
|
|
|
else { // check if Runtime still running
|
|
|
|
Runtime * tr = runtime ();
|
|
|
|
if (tr->state () < Runtime::timings_stopped) {
|
|
|
|
if (tr->state () == Runtime::timings_started)
|
|
|
|
tr->propagateStop (false);
|
|
|
|
return; // still running, wait for runtime to finish
|
|
|
|
}
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodeRefListPtr SMIL::TimedMrl::listeners (unsigned int id) {
|
|
|
|
if (id == event_stopped)
|
|
|
|
return m_StoppedListeners;
|
|
|
|
else if (id == event_started)
|
|
|
|
return m_StartedListeners;
|
|
|
|
else if (id == event_to_be_started)
|
|
|
|
return m_StartListeners;
|
|
|
|
kdWarning () << "unknown event requested" << endl;
|
|
|
|
return NodeRefListPtr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::TimedMrl::handleEvent (EventPtr event) {
|
|
|
|
unsigned int id = event->id ();
|
|
|
|
switch (id) {
|
|
|
|
case event_timer: {
|
|
|
|
TimerEvent * te = static_cast <TimerEvent *> (event.ptr ());
|
|
|
|
if (te && te->timer_info) {
|
|
|
|
if (te->timer_info->event_id == started_timer_id)
|
|
|
|
runtime ()->started ();
|
|
|
|
else if (te->timer_info->event_id == stopped_timer_id)
|
|
|
|
runtime ()->stopped ();
|
|
|
|
else if (te->timer_info->event_id == start_timer_id)
|
|
|
|
runtime ()->propagateStart ();
|
|
|
|
else if (te->timer_info->event_id == dur_timer_id)
|
|
|
|
runtime ()->propagateStop (true);
|
|
|
|
else
|
|
|
|
kdWarning () << "unhandled timer event" << endl;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
if (m_runtime)
|
|
|
|
m_runtime->processEvent (id);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::TimedMrl::getNewRuntime () {
|
|
|
|
return new Runtime (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::TimedMrl::parseParam (const TrieString ¶, const TQString &value) {
|
|
|
|
if (para.startsWith (StringPool::attr_fill)) {
|
|
|
|
Fill * f = &fill;
|
|
|
|
if (para != StringPool::attr_fill) {
|
|
|
|
f = &fill_def;
|
|
|
|
*f = fill_inherit;
|
|
|
|
} else
|
|
|
|
*f = fill_default;
|
|
|
|
fill_active = fill_auto;
|
|
|
|
if (value == "freeze")
|
|
|
|
*f = fill_freeze;
|
|
|
|
else if (value == "hold")
|
|
|
|
*f = fill_hold;
|
|
|
|
else if (value == "auto")
|
|
|
|
*f = fill_auto;
|
|
|
|
else if (value == "remove")
|
|
|
|
*f = fill_remove;
|
|
|
|
else if (value == "transition")
|
|
|
|
*f = fill_transition;
|
|
|
|
if (fill == fill_default) {
|
|
|
|
if (fill_def == fill_inherit)
|
|
|
|
fill_active = getDefaultFill (this);
|
|
|
|
else
|
|
|
|
fill_active = fill_def;
|
|
|
|
} else
|
|
|
|
fill_active = fill;
|
|
|
|
} else if (!runtime ()->parseParam (para, value)) {
|
|
|
|
if (para == StringPool::attr_src) //block Mrl src parsing for now
|
|
|
|
kdDebug() << "parseParam src on " << nodeName() << endl;
|
|
|
|
else
|
|
|
|
Mrl::parseParam (para, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
Runtime::DurationItem * SMIL::TimedMrl::getDuration (NodePtr n) {
|
|
|
|
if (!isTimedMrl (n) || !n->active ())
|
|
|
|
return 0L;
|
|
|
|
TimedMrl * tm = convertNode <SMIL::TimedMrl> (n);
|
|
|
|
return &tm->runtime ()->durations [Runtime::duration_time];
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::TimedMrl::keepContent (Node *n) {
|
|
|
|
if (isTimedMrl (n)) {
|
|
|
|
TimedMrl * tm = convertNode <SMIL::TimedMrl> (n);
|
|
|
|
if (tm->runtime ()->timingstate == Runtime::timings_started)
|
|
|
|
return true;
|
|
|
|
Node *p = n->parentNode ();
|
|
|
|
Node *np = tm;
|
|
|
|
while (p && id_node_body != p->id && !isTimedMrl (p)) {
|
|
|
|
np = p;
|
|
|
|
p = p->parentNode ().ptr (); // skip anchors
|
|
|
|
}
|
|
|
|
if (tm->m_runtime && p && p->active ()) {
|
|
|
|
if (tm->runtime ()->timingstate == Runtime::timings_stopped)
|
|
|
|
switch (tm->fill_active) {
|
|
|
|
case fill_hold: // keep while parent active
|
|
|
|
return true;
|
|
|
|
case fill_freeze: // keep in parent duration
|
|
|
|
if (p->unfinished() &&
|
|
|
|
(p->id == SMIL::id_node_par ||
|
|
|
|
p->id == SMIL::id_node_excl ||
|
|
|
|
p->id == SMIL::id_node_switch ||
|
|
|
|
p->lastChild().ptr () == np))
|
|
|
|
return true;
|
|
|
|
// else fall through
|
|
|
|
case fill_default: // as freeze when no duration is set
|
|
|
|
case fill_auto: // or when parent finished w/o duration
|
|
|
|
return keepContent (p) &&
|
|
|
|
(p->id == SMIL::id_node_par ||
|
|
|
|
p->id == SMIL::id_node_excl ||
|
|
|
|
p->id == SMIL::id_node_switch ||
|
|
|
|
p->lastChild().ptr () == np) &&
|
|
|
|
tm->runtime ()->durTime ().durval == Runtime::dur_timer &&
|
|
|
|
!tm->runtime ()->durTime ().offset;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT SMIL::TimedMrl::Fill SMIL::TimedMrl::getDefaultFill (NodePtr n) {
|
|
|
|
for (NodePtr p = n->parentNode (); p; p = p->parentNode ())
|
|
|
|
if (isTimedMrl (p)) {
|
|
|
|
SMIL::TimedMrl * tm = convertNode<SMIL::TimedMrl>(p);
|
|
|
|
if (tm->fill_def != fill_inherit)
|
|
|
|
return tm->fill_def;
|
|
|
|
else if (tm->fill == fill_default)
|
|
|
|
return tm->fill_active; // assume parent figured out this
|
|
|
|
} else if (p->id == SMIL::id_node_smil)
|
|
|
|
break;
|
|
|
|
return fill_auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::GroupBase::childFromTag (const TQString & tag) {
|
|
|
|
Element * elm = fromScheduleGroup (m_doc, tag);
|
|
|
|
if (!elm) elm = fromMediaContentGroup (m_doc, tag);
|
|
|
|
if (!elm) elm = fromContentControlGroup (m_doc, tag);
|
|
|
|
if (!elm) elm = fromAnimateGroup (m_doc, tag);
|
|
|
|
if (elm)
|
|
|
|
return elm;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::GroupBase::finish () {
|
|
|
|
setState (state_finished); // avoid recurstion through childDone
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (keepContent (e)) {
|
|
|
|
if (e->unfinished ())
|
|
|
|
e->finish ();
|
|
|
|
} else if (e->active ())
|
|
|
|
e->deactivate ();
|
|
|
|
TimedMrl::finish ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::GroupBase::deactivate () {
|
|
|
|
setState (state_deactivated); // avoid recurstion through childDone
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (e->active ())
|
|
|
|
e->deactivate ();
|
|
|
|
TimedMrl::deactivate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::GroupBase::setJumpNode (NodePtr n) {
|
|
|
|
NodePtr child = n;
|
|
|
|
if (state > state_init) {
|
|
|
|
for (NodePtr c = firstChild (); c; c = c->nextSibling ())
|
|
|
|
if (c->active ())
|
|
|
|
c->reset ();
|
|
|
|
for (NodePtr c = n->parentNode (); c; c = c->parentNode ()) {
|
|
|
|
if (c.ptr () == this || c->id == id_node_body)
|
|
|
|
break;
|
|
|
|
if (c->id >= id_node_first_group && c->id <= id_node_last_group)
|
|
|
|
convertNode <GroupBase> (c)->jump_node = child;
|
|
|
|
child = c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
jump_node = child;
|
|
|
|
state = state_activated;
|
|
|
|
init ();
|
|
|
|
runtime()->beginAndStart (); // undefer through begin()
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// SMIL::Body was here
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Par::begin () {
|
|
|
|
jump_node = 0L; // TODO: adjust timings
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
e->activate ();
|
|
|
|
GroupBase::begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Par::reset () {
|
|
|
|
GroupBase::reset ();
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
e->reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Par::childDone (NodePtr) {
|
|
|
|
if (unfinished ()) {
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ()) {
|
|
|
|
if (e->unfinished ())
|
|
|
|
return; // not all finished
|
|
|
|
}
|
|
|
|
Runtime * tr = runtime ();
|
|
|
|
if (tr->state () == Runtime::timings_started) {
|
|
|
|
Runtime::Duration dv = tr->durTime ().durval;
|
|
|
|
if ((dv == Runtime::dur_timer && !tr->durTime ().offset)
|
|
|
|
|| dv == Runtime::dur_media)
|
|
|
|
tr->propagateStop (false);
|
|
|
|
return; // still running, wait for runtime to finish
|
|
|
|
}
|
|
|
|
finish (); // we're done
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Seq::begin () {
|
|
|
|
if (jump_node) {
|
|
|
|
for (NodePtr c = firstChild (); c; c = c->nextSibling ())
|
|
|
|
if (c == jump_node) {
|
|
|
|
jump_node = 0L;
|
|
|
|
c->activate ();
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
c->state = state_activated; // TODO: ..
|
|
|
|
if (c->isElementNode ())
|
|
|
|
convertNode <Element> (c)->init ();
|
|
|
|
c->state = state_finished; // TODO: ..
|
|
|
|
}
|
|
|
|
} else if (firstChild ())
|
|
|
|
firstChild ()->activate ();
|
|
|
|
GroupBase::begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Seq::childDone (NodePtr child) {
|
|
|
|
if (unfinished ()) {
|
|
|
|
if (state != state_deferred) {
|
|
|
|
if (!keepContent (child) && child->active ())
|
|
|
|
child->deactivate ();
|
|
|
|
if (child->nextSibling ())
|
|
|
|
child->nextSibling ()->activate ();
|
|
|
|
else
|
|
|
|
finish ();
|
|
|
|
} else if (jump_node)
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Excl::begin () {
|
|
|
|
//kdDebug () << "SMIL::Excl::begin" << endl;
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
e->activate ();
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (isTimedMrl (e)) {
|
|
|
|
SMIL::TimedMrl * tm = static_cast <SMIL::TimedMrl *> (e.ptr ());
|
|
|
|
if (tm) { // make aboutToStart connection with TimedMrl children
|
|
|
|
ConnectionPtr c = tm->connectTo (this, event_to_be_started);
|
|
|
|
started_event_list.append (new ConnectionStoreItem (c));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GroupBase::begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Excl::deactivate () {
|
|
|
|
started_event_list.clear (); // auto disconnect on destruction of data items
|
|
|
|
GroupBase::deactivate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Excl::childDone (NodePtr /*child*/) {
|
|
|
|
// first check if somenode has taken over
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (isTimedMrl (e)) {
|
|
|
|
Runtime *tr = convertNode <SMIL::TimedMrl> (e)->runtime();
|
|
|
|
if (tr->state () == Runtime::timings_started)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// now finish unless 'dur="indefinite/some event/.."'
|
|
|
|
Runtime * tr = runtime ();
|
|
|
|
if (tr->state () == Runtime::timings_started)
|
|
|
|
tr->propagateStop (false); // still running, wait for runtime to finish
|
|
|
|
else
|
|
|
|
finish (); // we're done
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::Excl::handleEvent (EventPtr event) {
|
|
|
|
if (event->id () == event_to_be_started) {
|
|
|
|
ToBeStartedEvent * se = static_cast <ToBeStartedEvent *> (event.ptr ());
|
|
|
|
//kdDebug () << "Excl::handleEvent " << se->node->nodeName()<<endl;
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ()) {
|
|
|
|
if (e == se->node) // stop all _other_ child elements
|
|
|
|
continue;
|
|
|
|
if (!isTimedMrl (e))
|
|
|
|
continue; // definitely a stowaway
|
|
|
|
convertNode<SMIL::TimedMrl>(e)->runtime()->propagateStop(true);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return TimedMrl::handleEvent (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Switch::begin () {
|
|
|
|
//kdDebug () << "SMIL::Switch::activate" << endl;
|
|
|
|
PlayListNotify * n = document()->notify_listener;
|
|
|
|
int pref = 0, max = 0x7fffffff, currate = 0;
|
|
|
|
if (n)
|
|
|
|
n->bitRates (pref, max);
|
|
|
|
if (firstChild ()) {
|
|
|
|
NodePtr fallback;
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (e->isElementNode ()) {
|
|
|
|
Element *elm = convertNode <Element> (e);
|
|
|
|
TQString lang = elm->getAttribute ("systemLanguage");
|
|
|
|
if (!lang.isEmpty ()) {
|
|
|
|
lang = lang.replace (TQChar ('-'), TQChar ('_'));
|
|
|
|
char *clang = getenv ("LANG");
|
|
|
|
if (!clang) {
|
|
|
|
if (!fallback)
|
|
|
|
fallback = e;
|
|
|
|
} else if (TQString (clang).lower ().startsWith (lang)) {
|
|
|
|
chosenOne = e;
|
|
|
|
} else if (!fallback) {
|
|
|
|
fallback = e->nextSibling ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (e->id == id_node_audio_video) {
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (e);
|
|
|
|
if (!chosenOne) {
|
|
|
|
chosenOne = e;
|
|
|
|
currate = mt->bitrate;
|
|
|
|
} else if (int (mt->bitrate) <= max) {
|
|
|
|
int delta1 = pref > currate ? pref-currate : currate-pref;
|
|
|
|
int delta2 = pref > int (mt->bitrate) ? pref-mt->bitrate : mt->bitrate-pref;
|
|
|
|
if (delta2 < delta1) {
|
|
|
|
chosenOne = e;
|
|
|
|
currate = mt->bitrate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (!fallback && e->isPlayable ())
|
|
|
|
fallback = e;
|
|
|
|
}
|
|
|
|
if (!chosenOne)
|
|
|
|
chosenOne = (fallback ? fallback : firstChild ());
|
|
|
|
chosenOne->activate ();
|
|
|
|
}
|
|
|
|
GroupBase::begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Switch::deactivate () {
|
|
|
|
Element::deactivate ();
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ())
|
|
|
|
if (e->active ()) {
|
|
|
|
e->deactivate ();
|
|
|
|
break; // deactivate only the one running
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Switch::reset () {
|
|
|
|
Element::reset ();
|
|
|
|
for (NodePtr e = firstChild (); e; e = e->nextSibling ()) {
|
|
|
|
if (e->state != state_init)
|
|
|
|
e->reset ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Switch::childDone (NodePtr child) {
|
|
|
|
if (child->state == state_finished)
|
|
|
|
child->deactivate ();
|
|
|
|
//kdDebug () << "SMIL::Switch::childDone" << endl;
|
|
|
|
finish (); // only one child can run
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::LinkingBase::LinkingBase (NodePtr & d, short id)
|
|
|
|
: Element(d, id), show (show_replace) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::LinkingBase::deactivate () {
|
|
|
|
mediatype_activated = 0L;
|
|
|
|
mediatype_attach = 0L;
|
|
|
|
Element::deactivate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::LinkingBase::parseParam(const TrieString ¶, const TQString &val) {
|
|
|
|
if (para == StringPool::attr_href) {
|
|
|
|
href = val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::Anchor::Anchor (NodePtr & d)
|
|
|
|
: LinkingBase (d, id_node_anchor) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Anchor::activate () {
|
|
|
|
init ();
|
|
|
|
for (NodePtr c = firstChild(); c; c = c->nextSibling ())
|
|
|
|
if (c->id >=id_node_first_mediatype && c->id <=id_node_last_mediatype) {
|
|
|
|
mediatype_activated = c->connectTo (this, event_activated);
|
|
|
|
mediatype_attach = c->connectTo (this, mediatype_attached);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Element::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Anchor::childDone (NodePtr child) {
|
|
|
|
if (unfinished ()) {
|
|
|
|
if (child->nextSibling ())
|
|
|
|
child->nextSibling ()->activate ();
|
|
|
|
else
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NodePtr SMIL::Anchor::childFromTag (const TQString & tag) {
|
|
|
|
return fromMediaContentGroup (m_doc, tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::Area::Area (NodePtr & d, const TQString & t)
|
|
|
|
: LinkingBase (d, id_node_area), coords (0L), nr_coords (0), tag (t) {}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::Area::~Area () {
|
|
|
|
delete [] coords;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Area::activate () {
|
|
|
|
init ();
|
|
|
|
if (parentNode () &&
|
|
|
|
parentNode ()->id >= id_node_first_mediatype &&
|
|
|
|
parentNode ()->id <= id_node_last_mediatype) {
|
|
|
|
mediatype_activated = parentNode ()->connectTo (this, event_activated);
|
|
|
|
mediatype_attach = parentNode ()->connectTo (this, mediatype_attached);
|
|
|
|
}
|
|
|
|
Element::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::Area::parseParam (const TrieString & para, const TQString & val) {
|
|
|
|
if (para == "coords") {
|
|
|
|
delete [] coords;
|
|
|
|
TQStringList clist = TQStringList::split (TQString (","), val);
|
|
|
|
nr_coords = clist.count ();
|
|
|
|
coords = new SizeType [nr_coords];
|
|
|
|
for (int i = 0; i < nr_coords; ++i)
|
|
|
|
coords[i] = clist[i];
|
|
|
|
} else
|
|
|
|
LinkingBase::parseParam (para, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodeRefListPtr SMIL::Area::listeners (unsigned int id) {
|
|
|
|
NodeRefListPtr l = mouse_listeners.listeners (id);
|
|
|
|
if (l)
|
|
|
|
return l;
|
|
|
|
return Element::listeners (id);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::MediaType::MediaType (NodePtr &d, const TQString &t, short id)
|
|
|
|
: TimedMrl (d, id), m_type (t), bitrate (0), trans_step (0), trans_steps (0),
|
|
|
|
sensitivity (sens_opaque), trans_out_active (false),
|
|
|
|
m_MediaAttached (new NodeRefList) {
|
|
|
|
view_mode = Mrl::WindowMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::MediaType::childFromTag (const TQString & tag) {
|
|
|
|
Element * elm = fromContentControlGroup (m_doc, tag);
|
|
|
|
if (!elm) elm = fromParamGroup (m_doc, tag);
|
|
|
|
if (!elm) elm = fromAnimateGroup (m_doc, tag);
|
|
|
|
if (elm)
|
|
|
|
return elm;
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::closed () {
|
|
|
|
external_tree = findExternalTree (this);
|
|
|
|
Mrl *mrl = external_tree ? external_tree->mrl () : NULL;
|
|
|
|
if (mrl) {
|
|
|
|
width = mrl->width;
|
|
|
|
height = mrl->height;
|
|
|
|
}
|
|
|
|
TimedMrl::closed ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
void SMIL::MediaType::parseParam (const TrieString ¶, const TQString & val) {
|
|
|
|
bool update_surface = true;
|
|
|
|
if (para == "fit") {
|
|
|
|
const char * cval = val.ascii ();
|
|
|
|
if (!cval)
|
|
|
|
fit = fit_hidden;
|
|
|
|
else if (!strcmp (cval, "fill"))
|
|
|
|
fit = fit_fill;
|
|
|
|
else if (!strcmp (cval, "hidden"))
|
|
|
|
fit = fit_hidden;
|
|
|
|
else if (!strcmp (cval, "meet"))
|
|
|
|
fit = fit_meet;
|
|
|
|
else if (!strcmp (cval, "scroll"))
|
|
|
|
fit = fit_scroll;
|
|
|
|
else if (!strcmp (cval, "slice"))
|
|
|
|
fit = fit_slice;
|
|
|
|
else
|
|
|
|
fit = fit_hidden;
|
|
|
|
} else if (para == "rn:mediaOpacity") {
|
|
|
|
opacity = (int) SizeType (val).size (100);
|
|
|
|
} else if (para == "system-bitrate") {
|
|
|
|
bitrate = val.toInt ();
|
|
|
|
} else if (para == StringPool::attr_type) {
|
|
|
|
mimetype = val;
|
|
|
|
} else if (para == "transIn") {
|
|
|
|
trans_in = findTransition (this, val);
|
|
|
|
if (!trans_in)
|
|
|
|
kdWarning() << "Transition " << val << " not found in head" << endl;
|
|
|
|
} else if (para == "transOut") {
|
|
|
|
trans_out = findTransition (this, val);
|
|
|
|
if (!trans_out)
|
|
|
|
kdWarning() << "Transition " << val << " not found in head" << endl;
|
|
|
|
} else if (para == "sensitivity") {
|
|
|
|
if (val == "transparent")
|
|
|
|
sensitivity = sens_transparent;
|
|
|
|
//else if (val == "percentage") // TODO
|
|
|
|
// sensitivity = sens_percentage;
|
|
|
|
else
|
|
|
|
sensitivity = sens_opaque;
|
|
|
|
} else if (sizes.setSizeParam (para, val, update_surface)) {
|
|
|
|
if (!update_surface && fit_hidden == fit &&
|
|
|
|
sub_surface
|
|
|
|
#ifdef HAVE_CAIRO
|
|
|
|
&& sub_surface->surface
|
|
|
|
#endif
|
|
|
|
) {
|
|
|
|
boundsUpdate ();
|
|
|
|
return; // preserved surface by recalculationg sub_surface top-left
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TimedMrl::parseParam (para, val);
|
|
|
|
}
|
|
|
|
if (sub_surface)
|
|
|
|
sub_surface->repaint ();
|
|
|
|
resetSurface ();
|
|
|
|
if (surface ())
|
|
|
|
sub_surface->repaint ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::boundsUpdate () {
|
|
|
|
SMIL::RegionBase *rb = convertNode <SMIL::RegionBase> (region_node);
|
|
|
|
if (rb && sub_surface) {
|
|
|
|
SRect new_bounds = calculateBounds ();
|
|
|
|
SRect repaint_rect = sub_surface->bounds.unite (new_bounds);
|
|
|
|
sub_surface->bounds = new_bounds;
|
|
|
|
rb->repaint (repaint_rect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::activate () {
|
|
|
|
trans_out_active = false;
|
|
|
|
fit = fit_hidden;
|
|
|
|
opacity = 100;
|
|
|
|
init (); // sets all attributes
|
|
|
|
setState (state_activated);
|
|
|
|
for (NodePtr c = firstChild (); c; c = c->nextSibling ())
|
|
|
|
if (c != external_tree) {
|
|
|
|
// activate param/set/animate.. children
|
|
|
|
c->activate ();
|
|
|
|
break; // childDone will handle next siblings
|
|
|
|
}
|
|
|
|
runtime ()->begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::deactivate () {
|
|
|
|
region_paint = 0L;
|
|
|
|
region_mouse_enter = 0L;
|
|
|
|
region_mouse_leave = 0L;
|
|
|
|
region_mouse_click = 0L;
|
|
|
|
region_attach = 0L;
|
|
|
|
trans_step = trans_steps = 0;
|
|
|
|
if (region_node)
|
|
|
|
convertNode <SMIL::RegionBase> (region_node)->repaint ();
|
|
|
|
if (trans_timer)
|
|
|
|
document ()->cancelTimer (trans_timer);
|
|
|
|
if (trans_out_timer)
|
|
|
|
document ()->cancelTimer (trans_out_timer);
|
|
|
|
TimedMrl::deactivate (); // keep region for runtime rest
|
|
|
|
region_node = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::begin () {
|
|
|
|
SMIL::Smil * s = Smil::findSmilNode (parentNode ().ptr ());
|
|
|
|
SMIL::Region * r = s ?
|
|
|
|
findRegion (s->layout_node, param (StringPool::attr_region)) : 0L;
|
|
|
|
MediaTypeRuntime *tr = static_cast<MediaTypeRuntime*>(runtime ());
|
|
|
|
if (trans_timer) // eg transOut and we're repeating
|
|
|
|
document ()->cancelTimer (trans_timer);
|
|
|
|
if (r) {
|
|
|
|
region_node = r;
|
|
|
|
region_mouse_enter = r->connectTo (this, event_inbounds);
|
|
|
|
region_mouse_leave = r->connectTo (this, event_outbounds);
|
|
|
|
region_mouse_click = r->connectTo (this, event_activated);
|
|
|
|
region_attach = r->connectTo (this, mediatype_attached);
|
|
|
|
r->repaint ();
|
|
|
|
tr->clipStart ();
|
|
|
|
Transition * trans = convertNode <Transition> (trans_in);
|
|
|
|
if (trans && trans->supported ()) {
|
|
|
|
active_trans = trans_in;
|
|
|
|
trans_step = 1;
|
|
|
|
if (Transition::Fade == trans->type) {
|
|
|
|
trans_steps = trans->dur;
|
|
|
|
trans_timer = document()->setTimeout(this, 100, trans_timer_id);
|
|
|
|
} else {
|
|
|
|
trans_steps = 4 * trans->dur;
|
|
|
|
trans_timer = document()->setTimeout(this, 25, trans_timer_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Runtime::dur_timer == tr->durTime().durval &&
|
|
|
|
tr->durTime().offset > 0) {
|
|
|
|
// FIXME: also account for fill duration
|
|
|
|
trans = convertNode <Transition> (trans_out);
|
|
|
|
if (trans && trans->supported () &&
|
|
|
|
(int) trans->dur < tr->durTime().offset)
|
|
|
|
trans_out_timer = document()->setTimeout (
|
|
|
|
this,
|
|
|
|
(tr->durTime().offset - trans->dur) * 100,
|
|
|
|
trans_out_timer_id);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
kdWarning () << nodeName() << "::begin " << src << " region '" <<
|
|
|
|
param (StringPool::attr_region) << "' not found" << endl;
|
|
|
|
TimedMrl::begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::finish () {
|
|
|
|
if (trans_timer && !keepContent (this)) {
|
|
|
|
document ()->cancelTimer (trans_timer);
|
|
|
|
ASSERT(!trans_timer);
|
|
|
|
}
|
|
|
|
if (region_node)
|
|
|
|
convertNode <SMIL::RegionBase> (region_node)->repaint ();
|
|
|
|
TimedMrl::finish ();
|
|
|
|
static_cast <MediaTypeRuntime *> (runtime ())->clipStop ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Re-implement from TimedMrl, because we may have children like
|
|
|
|
* param/set/animatie that should all be activate, but also other smil or imfl
|
|
|
|
* documents, that should only be activated if the runtime has started
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::childDone (NodePtr child) {
|
|
|
|
bool child_doc = child->mrl () && child->mrl ()->opener.ptr () == this;
|
|
|
|
if (child_doc) {
|
|
|
|
child->deactivate (); // should only if fill not is freeze or hold
|
|
|
|
} else if (active ()) { // traverse param or area children
|
|
|
|
for (NodePtr c = child->nextSibling(); c; c = c->nextSibling ())
|
|
|
|
if (!c->mrl () || c->mrl ()->opener.ptr () != this ) {
|
|
|
|
c->activate ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Runtime * tr = runtime ();
|
|
|
|
if (tr->state () < Runtime::timings_stopped) {
|
|
|
|
if (tr->state () == Runtime::timings_started)
|
|
|
|
tr->propagateStop (child_doc); // what about repeat_count ..
|
|
|
|
return; // still running, wait for runtime to finish
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (active ())
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::MediaType::needsVideoWidget () {
|
|
|
|
MediaTypeRuntime * mtr = static_cast <MediaTypeRuntime *> (runtime ());
|
|
|
|
SMIL::Smil * s = SMIL::Smil::findSmilNode (this);
|
|
|
|
Node * link = s ? s->current_av_media_type.ptr () : 0L;
|
|
|
|
return ((link == this || !link) &&
|
|
|
|
(state == state_deferred || unfinished ()) && link &&
|
|
|
|
mtr->state () != Runtime::timings_stopped &&
|
|
|
|
(!strcmp (nodeName (), "video") || !strcmp (nodeName (), "ref")) &&
|
|
|
|
surface ());
|
|
|
|
}
|
|
|
|
|
|
|
|
SurfacePtr SMIL::MediaType::getSurface (NodePtr node) {
|
|
|
|
resetSurface ();
|
|
|
|
Surface *s = surface ();
|
|
|
|
if (s && node)
|
|
|
|
s->node = node;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Surface *SMIL::MediaType::surface () {
|
|
|
|
if (!keepContent (this)) {
|
|
|
|
resetSurface ();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!sub_surface) {
|
|
|
|
SMIL::RegionBase *rb = convertNode <SMIL::RegionBase> (region_node);
|
|
|
|
if (rb && rb->surface ()) {
|
|
|
|
SRect rect = calculateBounds ();
|
|
|
|
sub_surface =rb->region_surface->createSurface (this, rect);
|
|
|
|
if (width > 0 && height > 0) {
|
|
|
|
sub_surface->xscale = 1.0 * rect.width () / width;
|
|
|
|
sub_surface->yscale = 1.0 * rect.height () / height;
|
|
|
|
}
|
|
|
|
//kdDebug() << sub_surface.ptr() << " " << nodeName() << " " << src << " " << rr.width() << "," << rr.height() << " => " << x << "," << y << w << "," << h << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sub_surface.ptr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::MediaType::resetSurface () {
|
|
|
|
if (sub_surface)
|
|
|
|
sub_surface->remove ();
|
|
|
|
sub_surface = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT SRect SMIL::MediaType::calculateBounds () {
|
|
|
|
SMIL::RegionBase *rb = convertNode <SMIL::RegionBase> (region_node);
|
|
|
|
if (rb && rb->surface ()) {
|
|
|
|
SRect rr = rb->region_surface->bounds;
|
|
|
|
Single x, y, w = width, h = height;
|
|
|
|
sizes.calcSizes (this, rr.width(), rr.height(), x, y, w, h);
|
|
|
|
if (width > 0 && height > 0 && w > 0 && h > 0)
|
|
|
|
switch (fit) {
|
|
|
|
case fit_meet: {
|
|
|
|
float iasp = 1.0 * width / height;
|
|
|
|
float rasp = 1.0 * w / h;
|
|
|
|
if (iasp > rasp)
|
|
|
|
h = height * w / width;
|
|
|
|
else
|
|
|
|
w = width * h / height;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case fit_scroll:
|
|
|
|
case fit_hidden:
|
|
|
|
w = width;
|
|
|
|
h = height;
|
|
|
|
break;
|
|
|
|
case fit_slice: {
|
|
|
|
float iasp = 1.0 * width / height;
|
|
|
|
float rasp = 1.0 * w / h;
|
|
|
|
if (iasp > rasp)
|
|
|
|
w = width * h / height;
|
|
|
|
else
|
|
|
|
h = height * w / width;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {} // fit_fill
|
|
|
|
}
|
|
|
|
return SRect (x, y, w, h);
|
|
|
|
}
|
|
|
|
return SRect ();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SMIL::MediaType::handleEvent (EventPtr event) {
|
|
|
|
Surface *s = surface();
|
|
|
|
switch (event->id ()) {
|
|
|
|
case event_postponed: {
|
|
|
|
PostponedEvent * pe = static_cast <PostponedEvent *> (event.ptr ());
|
|
|
|
static_cast<MediaTypeRuntime*>(runtime())->postpone (pe->is_postponed);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case event_timer: {
|
|
|
|
TimerEvent * te = static_cast <TimerEvent *> (event.ptr ());
|
|
|
|
if (te && te->timer_info) {
|
|
|
|
if (te->timer_info->event_id == trans_timer_id) {
|
|
|
|
if (trans_step >= trans_steps)
|
|
|
|
active_trans = NULL;
|
|
|
|
else
|
|
|
|
te->interval = trans_step++ < trans_steps;
|
|
|
|
if (s && s->parentNode())
|
|
|
|
s->parentNode()->repaint (s->bounds);
|
|
|
|
return true;
|
|
|
|
} else if (te->timer_info->event_id == trans_out_timer_id) {
|
|
|
|
active_trans = trans_out;
|
|
|
|
Transition * trans = convertNode <Transition> (trans_out);
|
|
|
|
if (trans) {
|
|
|
|
if (trans_timer) // eg. overlapping transIn/transOut
|
|
|
|
document ()->cancelTimer (trans_timer);
|
|
|
|
trans_step = 1;
|
|
|
|
if (Transition::Fade == trans->type) {
|
|
|
|
trans_steps = trans->dur;
|
|
|
|
trans_timer = document()->setTimeout(this, 100, trans_timer_id);
|
|
|
|
} else {
|
|
|
|
trans_steps = 4 * trans->dur;
|
|
|
|
trans_timer = document()->setTimeout(this, 25, trans_timer_id);
|
|
|
|
}
|
|
|
|
trans_out_active = true;
|
|
|
|
if (s)
|
|
|
|
s->repaint ();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // fall through
|
|
|
|
default:
|
|
|
|
return TimedMrl::handleEvent (event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodeRefListPtr SMIL::MediaType::listeners (unsigned int id) {
|
|
|
|
NodeRefListPtr l = mouse_listeners.listeners (id);
|
|
|
|
if (l)
|
|
|
|
return l;
|
|
|
|
switch (id) {
|
|
|
|
case mediatype_attached:
|
|
|
|
return m_MediaAttached;
|
|
|
|
}
|
|
|
|
return TimedMrl::listeners (id);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT
|
|
|
|
SMIL::AVMediaType::AVMediaType (NodePtr & d, const TQString & t)
|
|
|
|
: SMIL::MediaType (d, t, id_node_audio_video) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::AVMediaType::childFromTag (const TQString & tag) {
|
|
|
|
return fromXMLDocumentTag (m_doc, tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::AVMediaType::defer () {
|
|
|
|
setState (state_deferred);
|
|
|
|
MediaTypeRuntime * mr = static_cast <MediaTypeRuntime *> (runtime ());
|
|
|
|
if (mr->state () == Runtime::timings_started)
|
|
|
|
mr->postpone_lock = document ()->postpone ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::AVMediaType::undefer () {
|
|
|
|
setState (state_activated);
|
|
|
|
MediaTypeRuntime * mr = static_cast <MediaTypeRuntime *> (runtime ());
|
|
|
|
if (mr->state () == Runtime::timings_started) {
|
|
|
|
mr->postpone_lock = 0L;
|
|
|
|
mr->started ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::AVMediaType::endOfFile () {
|
|
|
|
if (!active())
|
|
|
|
return; // backend eof after a reset
|
|
|
|
MediaTypeRuntime * mr = static_cast <MediaTypeRuntime *> (runtime ());
|
|
|
|
mr->postpone_lock = 0L;
|
|
|
|
mr->propagateStop (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::AVMediaType::getNewRuntime () {
|
|
|
|
return new AudioVideoData (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::AVMediaType::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::AVMediaType::expose () const {
|
|
|
|
return !src.isEmpty () && !external_tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT
|
|
|
|
SMIL::ImageMediaType::ImageMediaType (NodePtr & d)
|
|
|
|
: SMIL::MediaType (d, "img", id_node_img) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::ImageMediaType::getNewRuntime () {
|
|
|
|
return new ImageRuntime (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr SMIL::ImageMediaType::childFromTag (const TQString & tag) {
|
|
|
|
if (!strcmp (tag.latin1 (), "imfl"))
|
|
|
|
return new RP::Imfl (m_doc);
|
|
|
|
return SMIL::MediaType::childFromTag (tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::ImageMediaType::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT
|
|
|
|
SMIL::TextMediaType::TextMediaType (NodePtr & d)
|
|
|
|
: SMIL::MediaType (d, "text", id_node_text) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::TextMediaType::getNewRuntime () {
|
|
|
|
return new TextRuntime (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::TextMediaType::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT
|
|
|
|
SMIL::RefMediaType::RefMediaType (NodePtr & d)
|
|
|
|
: SMIL::MediaType (d, "ref", id_node_ref) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::RefMediaType::getNewRuntime () {
|
|
|
|
return new AudioVideoData (this); // FIXME check mimetype first
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::RefMediaType::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT SMIL::Brush::Brush (NodePtr & d)
|
|
|
|
: SMIL::MediaType (d, "brush", id_node_brush) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Brush::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::Brush::getNewRuntime () {
|
|
|
|
return new MediaTypeRuntime (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::Set::getNewRuntime () {
|
|
|
|
return new SetData (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime * SMIL::Animate::getNewRuntime () {
|
|
|
|
return new AnimateData (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::Animate::handleEvent (EventPtr event) {
|
|
|
|
if (event->id () == event_timer) {
|
|
|
|
TimerEvent * te = static_cast <TimerEvent *> (event.ptr ());
|
|
|
|
if (te && te->timer_info && te->timer_info->event_id == anim_timer_id) {
|
|
|
|
if (static_cast <AnimateData *> (runtime ())->timerTick () &&
|
|
|
|
te->timer_info)
|
|
|
|
te->interval = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TimedMrl::handleEvent (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Runtime *SMIL::AnimateMotion::getNewRuntime () {
|
|
|
|
return new AnimateMotionData (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool SMIL::AnimateMotion::handleEvent (EventPtr event) {
|
|
|
|
if (event->id () == event_timer) {
|
|
|
|
TimerEvent * te = static_cast <TimerEvent *> (event.ptr ());
|
|
|
|
if (te && te->timer_info && te->timer_info->event_id == anim_timer_id) {
|
|
|
|
if (static_cast <AnimateMotionData *> (runtime ())->timerTick () &&
|
|
|
|
te->timer_info)
|
|
|
|
te->interval = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TimedMrl::handleEvent (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void SMIL::Param::activate () {
|
|
|
|
setState (state_activated);
|
|
|
|
TQString name = getAttribute (StringPool::attr_name);
|
|
|
|
Node * parent = parentNode ().ptr ();
|
|
|
|
if (!name.isEmpty () && parent && parent->isElementNode ())
|
|
|
|
static_cast<Element*>(parent)->setParam (name,
|
|
|
|
getAttribute (StringPool::attr_value));
|
|
|
|
Element::activate (); //finish (); // no livetime of itself, will deactivate
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::Region * n) {
|
|
|
|
visit (static_cast <SMIL::RegionBase *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::Layout * n) {
|
|
|
|
visit (static_cast <SMIL::RegionBase *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::Transition * n) {
|
|
|
|
visit (static_cast <Element *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::TimedMrl * n) {
|
|
|
|
visit (static_cast <Element *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::MediaType * n) {
|
|
|
|
visit (static_cast <SMIL::TimedMrl *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::ImageMediaType * n) {
|
|
|
|
visit (static_cast <SMIL::MediaType *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::TextMediaType * n) {
|
|
|
|
visit (static_cast <SMIL::MediaType *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::RefMediaType * n) {
|
|
|
|
visit (static_cast <SMIL::MediaType *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::AVMediaType * n) {
|
|
|
|
visit (static_cast <SMIL::MediaType *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::Brush * n) {
|
|
|
|
visit (static_cast <SMIL::MediaType *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::Anchor * n) {
|
|
|
|
visit (static_cast <SMIL::LinkingBase *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void Visitor::visit (SMIL::Area * n) {
|
|
|
|
visit (static_cast <SMIL::LinkingBase *> (n));
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT ImageRuntime::ImageRuntime (NodePtr e)
|
|
|
|
: MediaTypeRuntime (e), img_movie (0L)
|
|
|
|
{}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT ImageRuntime::~ImageRuntime () {
|
|
|
|
delete img_movie;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
bool ImageRuntime::parseParam (const TrieString & name, const TQString & val) {
|
|
|
|
//kdDebug () << "ImageRuntime::param " << name << "=" << val << endl;
|
|
|
|
if (name == StringPool::attr_src) {
|
|
|
|
killWGet ();
|
|
|
|
NodePtr element_protect = element;
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (!mt)
|
|
|
|
return false; // can not happen
|
|
|
|
if (mt->external_tree)
|
|
|
|
mt->removeChild (mt->external_tree);
|
|
|
|
mt->src = val;
|
|
|
|
if (!val.isEmpty ()) {
|
|
|
|
TQString abs = mt->absolutePath ();
|
|
|
|
cached_img.setUrl (abs);
|
|
|
|
if (cached_img.isEmpty ()) {
|
|
|
|
wget (abs);
|
|
|
|
} else {
|
|
|
|
mt->width = cached_img.data->image->width ();
|
|
|
|
mt->height = cached_img.data->image->height ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
return MediaTypeRuntime::parseParam (name, val);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start_timer timer expired, repaint if we have an image
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::started () {
|
|
|
|
if (element && downloading ()) {
|
|
|
|
postpone_lock = element->document ()->postpone ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
MediaTypeRuntime::started ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::clipStart () {
|
|
|
|
if (img_movie) {
|
|
|
|
img_movie->restart ();
|
|
|
|
if (img_movie->paused ())
|
|
|
|
img_movie->unpause ();
|
|
|
|
}
|
|
|
|
MediaTypeRuntime::clipStart ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::clipStop () {
|
|
|
|
if (img_movie && frame_nr)
|
|
|
|
img_movie->pause ();
|
|
|
|
MediaTypeRuntime::clipStop ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::remoteReady (TQByteArray & data) {
|
|
|
|
NodePtr element_protect = element; // note element is weak
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (data.size () && mt) {
|
|
|
|
mt->resetSurface ();
|
|
|
|
TQString mime = mimetype ();
|
|
|
|
kdDebug () << "ImageRuntime::remoteReady " << mime << " empty:" << cached_img.isEmpty () << " " << mt->src << endl;
|
|
|
|
if (mime.startsWith (TQString::fromLatin1 ("text/"))) {
|
|
|
|
TQTextStream ts (data, IO_ReadOnly);
|
|
|
|
readXML (element, ts, TQString ());
|
|
|
|
Mrl *mrl = mt->external_tree ? mt->external_tree->mrl () : NULL;
|
|
|
|
if (mrl) {
|
|
|
|
mt->width = mrl->width;
|
|
|
|
mt->height = mrl->height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!mt->external_tree && cached_img.isEmpty ()) {
|
|
|
|
delete img_movie;
|
|
|
|
img_movie = 0L;
|
|
|
|
TQImage *pix = new TQImage (data);
|
|
|
|
if (!pix->isNull ()) {
|
|
|
|
cached_img.data->image = pix;
|
|
|
|
img_movie = new TQMovie (data, data.size ());
|
|
|
|
img_movie->connectUpdate(this,TQ_SLOT(movieUpdated(const TQRect&)));
|
|
|
|
img_movie->connectStatus (this, TQ_SLOT (movieStatus (int)));
|
|
|
|
img_movie->connectResize(this,TQ_SLOT (movieResize(const TQSize&)));
|
|
|
|
frame_nr = 0;
|
|
|
|
mt->width = pix->width ();
|
|
|
|
mt->height = pix->height ();
|
|
|
|
if (mt->surface ())
|
|
|
|
mt->sub_surface->repaint ();
|
|
|
|
} else
|
|
|
|
delete pix;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
postpone_lock = 0L;
|
|
|
|
if (timingstate == timings_started)
|
|
|
|
started ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::movieUpdated (const TQRect &) {
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (mt && frame_nr++) {
|
|
|
|
mt->resetSurface ();
|
|
|
|
cached_img.setUrl (TQString ());
|
|
|
|
ASSERT (cached_img.data && cached_img.isEmpty ());
|
|
|
|
cached_img.data->image = new TQImage;
|
|
|
|
*cached_img.data->image = (img_movie->framePixmap ());
|
|
|
|
if (mt->surface())
|
|
|
|
mt->sub_surface->repaint ();
|
|
|
|
}
|
|
|
|
if (timingstate != timings_started && img_movie)
|
|
|
|
img_movie->pause ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::movieStatus (int s) {
|
|
|
|
if (element && element->state >= Node::state_began &&
|
|
|
|
SMIL::TimedMrl::keepContent (element)) {
|
|
|
|
if (s == TQMovie::EndOfMovie) {
|
|
|
|
propagateStop (false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::movieResize (const TQSize &) {
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (mt->surface ())
|
|
|
|
mt->sub_surface->repaint ();
|
|
|
|
//kdDebug () << "movieResize" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void ImageRuntime::postpone (bool b) {
|
|
|
|
kdDebug () << "ImageRuntime::postpone " << b << endl;
|
|
|
|
if (img_movie) {
|
|
|
|
if (!img_movie->paused () && b)
|
|
|
|
img_movie->pause ();
|
|
|
|
else if (img_movie->paused () && !b)
|
|
|
|
img_movie->unpause ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
namespace KMPlayer {
|
|
|
|
class TextRuntimePrivate {
|
|
|
|
public:
|
|
|
|
TextRuntimePrivate () {
|
|
|
|
reset ();
|
|
|
|
}
|
|
|
|
void reset () {
|
|
|
|
codec = 0L;
|
|
|
|
font = TQApplication::font ();
|
|
|
|
data.truncate (0);
|
|
|
|
}
|
|
|
|
TQByteArray data;
|
|
|
|
TQTextCodec * codec;
|
|
|
|
TQFont font;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT TextRuntime::TextRuntime (NodePtr e)
|
|
|
|
: MediaTypeRuntime (e), d (new TextRuntimePrivate) {
|
|
|
|
reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT TextRuntime::~TextRuntime () {
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void TextRuntime::reset () {
|
|
|
|
d->reset ();
|
|
|
|
font_size = d->font.pointSize ();
|
|
|
|
font_color = 0;
|
|
|
|
background_color = 0xffffff;
|
|
|
|
bg_opacity = 100;
|
|
|
|
halign = align_left;
|
|
|
|
MediaTypeRuntime::reset ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT
|
|
|
|
bool TextRuntime::parseParam (const TrieString & name, const TQString & val) {
|
|
|
|
//kdDebug () << "TextRuntime::parseParam " << name << "=" << val << endl;
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (!mt)
|
|
|
|
return false; // cannot happen
|
|
|
|
if (name == StringPool::attr_src) {
|
|
|
|
killWGet ();
|
|
|
|
mt->src = val;
|
|
|
|
d->data.resize (0);
|
|
|
|
if (!val.isEmpty ())
|
|
|
|
wget (mt->absolutePath ());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (name == "backgroundColor" || name == "background-color") {
|
|
|
|
background_color = val.isEmpty () ? 0xffffff : TQColor (val).rgb ();
|
|
|
|
} else if (name == "fontColor") {
|
|
|
|
font_color = val.isEmpty () ? 0 : TQColor (val).rgb ();
|
|
|
|
} else if (name == "charset") {
|
|
|
|
d->codec = TQTextCodec::codecForName (val.ascii ());
|
|
|
|
} else if (name == "fontFace") {
|
|
|
|
; //FIXME
|
|
|
|
} else if (name == "fontPtSize") {
|
|
|
|
font_size = val.isEmpty () ? d->font.pointSize () : val.toInt ();
|
|
|
|
} else if (name == "fontSize") {
|
|
|
|
font_size += val.isEmpty () ? d->font.pointSize () : val.toInt ();
|
|
|
|
} else if (name == "backgroundOpacity") {
|
|
|
|
bg_opacity = (int) SizeType (val).size (100);
|
|
|
|
} else if (name == "hAlign") {
|
|
|
|
const char * cval = val.ascii ();
|
|
|
|
if (!cval)
|
|
|
|
halign = align_left;
|
|
|
|
else if (!strcmp (cval, "center"))
|
|
|
|
halign = align_center;
|
|
|
|
else if (!strcmp (cval, "right"))
|
|
|
|
halign = align_right;
|
|
|
|
else
|
|
|
|
halign = align_left;
|
|
|
|
// TODO: expandTabs fontBackgroundColor fontSize fontStyle fontWeight hAlig vAlign wordWrap
|
|
|
|
} else
|
|
|
|
return MediaTypeRuntime::parseParam (name, val);
|
|
|
|
mt->resetSurface ();
|
|
|
|
if (mt->surface ())
|
|
|
|
mt->sub_surface->repaint ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start_timer timer expired, repaint if we have text
|
|
|
|
*/
|
|
|
|
KDE_NO_EXPORT void TextRuntime::started () {
|
|
|
|
if (element && downloading ()) {
|
|
|
|
postpone_lock = element->document ()->postpone ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
MediaTypeRuntime::started ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void TextRuntime::remoteReady (TQByteArray & data) {
|
|
|
|
TQString str (data);
|
|
|
|
SMIL::MediaType * mt = convertNode <SMIL::MediaType> (element);
|
|
|
|
if (mt && data.size ()) {
|
|
|
|
d->data = data;
|
|
|
|
mt->resetSurface ();
|
|
|
|
if (d->data.size () > 0 && !d->data [d->data.size () - 1])
|
|
|
|
d->data.resize (d->data.size () - 1); // strip zero terminate char
|
|
|
|
TQTextStream ts (d->data, IO_ReadOnly);
|
|
|
|
if (d->codec)
|
|
|
|
ts.setCodec (d->codec);
|
|
|
|
text = ts.read ();
|
|
|
|
if (mt->surface ())
|
|
|
|
mt->sub_surface->repaint ();
|
|
|
|
}
|
|
|
|
postpone_lock = 0L;
|
|
|
|
if (timingstate == timings_started)
|
|
|
|
started ();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "kmplayer_smil.moc"
|