|
|
|
/**
|
|
|
|
* Copyright (C) 2006 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 <tqcolor.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include "kmplayer_rp.h"
|
|
|
|
#include "kmplayer_smil.h"
|
|
|
|
|
|
|
|
using namespace KMPlayer;
|
|
|
|
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT RP::Imfl::Imfl (NodePtr & d)
|
|
|
|
: Mrl (d, id_node_imfl),
|
|
|
|
fit (fit_hidden),
|
|
|
|
duration (0),
|
|
|
|
needs_scene_img (0) {}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT RP::Imfl::~Imfl () {
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::closed () {
|
|
|
|
for (NodePtr n = firstChild (); n; n = n->nextSibling ())
|
|
|
|
if (RP::id_node_head == n->id) {
|
|
|
|
AttributePtr a = convertNode <Element> (n)->attributes ()->first ();
|
|
|
|
for (; a; a = a->nextSibling ()) {
|
|
|
|
if (StringPool::attr_width == a->name ()) {
|
|
|
|
width = a->value ().toInt ();
|
|
|
|
} else if (StringPool::attr_height == a->name ()) {
|
|
|
|
height = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "duration") {
|
|
|
|
int dur;
|
|
|
|
parseTime (a->value ().lower (), dur);
|
|
|
|
duration = dur;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::defer () {
|
|
|
|
kdDebug () << "RP::Imfl::defer " << endl;
|
|
|
|
setState (state_deferred);
|
|
|
|
for (Node * n = firstChild ().ptr (); n; n = n->nextSibling ().ptr ())
|
|
|
|
if (n->id == RP::id_node_image && !n->active ())
|
|
|
|
n->activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::activate () {
|
|
|
|
kdDebug () << "RP::Imfl::activate " << endl;
|
|
|
|
resolved = true;
|
|
|
|
setState (state_activated);
|
|
|
|
int timings_count = 0;
|
|
|
|
for (NodePtr n = firstChild (); n; n = n->nextSibling ())
|
|
|
|
switch (n->id) {
|
|
|
|
case RP::id_node_crossfade:
|
|
|
|
case RP::id_node_fadein:
|
|
|
|
case RP::id_node_fadeout:
|
|
|
|
case RP::id_node_fill:
|
|
|
|
case RP::id_node_wipe:
|
|
|
|
case RP::id_node_viewchange:
|
|
|
|
n->activate (); // set their start timers
|
|
|
|
timings_count++;
|
|
|
|
break;
|
|
|
|
case RP::id_node_image:
|
|
|
|
if (!n->active ())
|
|
|
|
n->activate ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (duration > 0)
|
|
|
|
duration_timer = document ()->setTimeout (this, duration * 100);
|
|
|
|
else if (!timings_count)
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::finish () {
|
|
|
|
kdDebug () << "RP::Imfl::finish " << endl;
|
|
|
|
Mrl::finish ();
|
|
|
|
if (duration_timer) {
|
|
|
|
document ()->cancelTimer (duration_timer);
|
|
|
|
duration_timer = 0;
|
|
|
|
}
|
|
|
|
for (NodePtr n = firstChild (); n; n = n->nextSibling ())
|
|
|
|
if (n->unfinished ())
|
|
|
|
n->finish ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::childDone (NodePtr) {
|
|
|
|
if (unfinished () && !duration_timer) {
|
|
|
|
for (NodePtr n = firstChild (); n; n = n->nextSibling ())
|
|
|
|
switch (n->id) {
|
|
|
|
case RP::id_node_crossfade:
|
|
|
|
case RP::id_node_fadein:
|
|
|
|
case RP::id_node_fadeout:
|
|
|
|
case RP::id_node_fill:
|
|
|
|
if (n->unfinished ())
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::deactivate () {
|
|
|
|
kdDebug () << "RP::Imfl::deactivate " << endl;
|
|
|
|
if (unfinished ())
|
|
|
|
finish ();
|
|
|
|
if (!active ())
|
|
|
|
return; // calling finish might call deactivate() as well
|
|
|
|
setState (state_deactivated);
|
|
|
|
for (NodePtr n = firstChild (); n; n = n->nextSibling ())
|
|
|
|
if (n->active ())
|
|
|
|
n->deactivate ();
|
|
|
|
rp_surface = Mrl::getSurface (0L);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool RP::Imfl::handleEvent (EventPtr event) {
|
|
|
|
if (event->id () == event_timer) {
|
|
|
|
TimerEvent * te = static_cast <TimerEvent *> (event.ptr ());
|
|
|
|
if (te->timer_info == duration_timer) {
|
|
|
|
kdDebug () << "RP::Imfl timer " << duration << endl;
|
|
|
|
duration_timer = 0;
|
|
|
|
if (unfinished ())
|
|
|
|
finish ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Surface *RP::Imfl::surface () {
|
|
|
|
if (!rp_surface) {
|
|
|
|
rp_surface = Mrl::getSurface (this);
|
|
|
|
if (rp_surface) {
|
|
|
|
if (width <= 0 || width > 32000)
|
|
|
|
width = rp_surface->bounds.width ();
|
|
|
|
if (height <= 0 || height > 32000)
|
|
|
|
height = rp_surface->bounds.height ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rp_surface.ptr ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT NodePtr RP::Imfl::childFromTag (const TQString & tag) {
|
|
|
|
const char * ctag = tag.latin1 ();
|
|
|
|
if (!strcmp (ctag, "head"))
|
|
|
|
return new DarkNode (m_doc, "head", RP::id_node_head);
|
|
|
|
else if (!strcmp (ctag, "image"))
|
|
|
|
return new RP::Image (m_doc);
|
|
|
|
else if (!strcmp (ctag, "fill"))
|
|
|
|
return new RP::Fill (m_doc);
|
|
|
|
else if (!strcmp (ctag, "wipe"))
|
|
|
|
return new RP::Wipe (m_doc);
|
|
|
|
else if (!strcmp (ctag, "viewchange"))
|
|
|
|
return new RP::ViewChange (m_doc);
|
|
|
|
else if (!strcmp (ctag, "crossfade"))
|
|
|
|
return new RP::Crossfade (m_doc);
|
|
|
|
else if (!strcmp (ctag, "fadein"))
|
|
|
|
return new RP::Fadein (m_doc);
|
|
|
|
else if (!strcmp (ctag, "fadeout"))
|
|
|
|
return new RP::Fadeout (m_doc);
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Imfl::repaint () {
|
|
|
|
if (!active ())
|
|
|
|
kdWarning () << "Spurious Imfl repaint" << endl;
|
|
|
|
else if (surface () && width > 0 && height > 0)
|
|
|
|
rp_surface->repaint (SRect (0, 0, width, height));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT RP::Image::Image (NodePtr & doc)
|
|
|
|
: Mrl (doc, id_node_image)
|
|
|
|
{}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT RP::Image::~Image () {
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Image::closed () {
|
|
|
|
src = getAttribute (StringPool::attr_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Image::activate () {
|
|
|
|
kdDebug () << "RP::Image::activate" << endl;
|
|
|
|
setState (state_activated);
|
|
|
|
isPlayable (); // update src attribute
|
|
|
|
cached_img.setUrl (absolutePath ());
|
|
|
|
if (cached_img.isEmpty ()) {
|
|
|
|
wget (absolutePath ());
|
|
|
|
} else {
|
|
|
|
width = cached_img.data->image->width ();
|
|
|
|
height = cached_img.data->image->height ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Image::begin () {
|
|
|
|
Node::begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Image::deactivate () {
|
|
|
|
cached_img.setUrl (TQString ());
|
|
|
|
if (img_surface) {
|
|
|
|
img_surface->remove ();
|
|
|
|
img_surface = NULL;
|
|
|
|
}
|
|
|
|
setState (state_deactivated);
|
|
|
|
postpone_lock = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Image::remoteReady (TQByteArray & data) {
|
|
|
|
kdDebug () << "RP::Image::remoteReady" << endl;
|
|
|
|
if (!data.isEmpty () && cached_img.isEmpty ()) {
|
|
|
|
TQImage * img = new TQImage (data);
|
|
|
|
if (!img->isNull ()) {
|
|
|
|
cached_img.data->image = img;
|
|
|
|
width = img->width ();
|
|
|
|
height = img->height ();
|
|
|
|
} else {
|
|
|
|
delete img;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
postpone_lock = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool RP::Image::isReady (bool postpone_if_not) {
|
|
|
|
if (downloading () && postpone_if_not)
|
|
|
|
postpone_lock = document ()->postpone ();
|
|
|
|
return !downloading ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT Surface *RP::Image::surface () {
|
|
|
|
if (!img_surface && !cached_img.isEmpty ()) {
|
|
|
|
Node * p = parentNode ().ptr ();
|
|
|
|
if (p && p->id == RP::id_node_imfl) {
|
|
|
|
Surface *ps = static_cast <RP::Imfl *> (p)->surface ();
|
|
|
|
if (ps)
|
|
|
|
img_surface = ps->createSurface (this,
|
|
|
|
SRect (0, 0, width, height));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return img_surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT RP::TimingsBase::TimingsBase (NodePtr & d, const short i)
|
|
|
|
: Element (d, i), x (0), y (0), w (0), h (0), start (0), duration (0) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::TimingsBase::activate () {
|
|
|
|
setState (state_activated);
|
|
|
|
x = y = w = h = 0;
|
|
|
|
srcx = srcy = srcw = srch = 0;
|
|
|
|
for (Attribute * a= attributes ()->first ().ptr (); a; a = a->nextSibling ().ptr ()) {
|
|
|
|
if (a->name () == StringPool::attr_target) {
|
|
|
|
for (NodePtr n = parentNode()->firstChild(); n; n= n->nextSibling())
|
|
|
|
if (convertNode <Element> (n)->
|
|
|
|
getAttribute ("handle") == a->value ())
|
|
|
|
target = n;
|
|
|
|
} else if (a->name () == "start") {
|
|
|
|
int dur;
|
|
|
|
parseTime (a->value ().lower (), dur);
|
|
|
|
start = dur;
|
|
|
|
} else if (a->name () == "duration") {
|
|
|
|
int dur;
|
|
|
|
parseTime (a->value ().lower (), dur);
|
|
|
|
duration = dur;
|
|
|
|
} else if (a->name () == "dstx") {
|
|
|
|
x = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "dsty") {
|
|
|
|
y = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "dstw") {
|
|
|
|
w = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "dsth") {
|
|
|
|
h = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "srcx") {
|
|
|
|
srcx = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "srcy") {
|
|
|
|
srcy = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "srcw") {
|
|
|
|
srcw = a->value ().toInt ();
|
|
|
|
} else if (a->name () == "srch") {
|
|
|
|
srch = a->value ().toInt ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
start_timer = document ()->setTimeout (this, start *100);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::TimingsBase::deactivate () {
|
|
|
|
if (unfinished ())
|
|
|
|
finish ();
|
|
|
|
setState (state_deactivated);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool RP::TimingsBase::handleEvent (EventPtr event) {
|
|
|
|
if (event->id () == event_timer) {
|
|
|
|
TimerEvent * te = static_cast <TimerEvent *> (event.ptr ());
|
|
|
|
if (te->timer_info == update_timer && duration > 0) {
|
|
|
|
update (100 * ++curr_step / duration);
|
|
|
|
te->interval = true;
|
|
|
|
} else if (te->timer_info == start_timer) {
|
|
|
|
start_timer = 0;
|
|
|
|
duration_timer = document ()->setTimeout (this, duration * 100);
|
|
|
|
begin ();
|
|
|
|
} else if (te->timer_info == duration_timer) {
|
|
|
|
duration_timer = 0;
|
|
|
|
update (100);
|
|
|
|
finish ();
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
} else if (event->id () == event_postponed) {
|
|
|
|
if (!static_cast <PostponedEvent *> (event.ptr ())->is_postponed) {
|
|
|
|
document_postponed = 0L; // disconnect
|
|
|
|
update (duration > 0 ? 0 : 100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::TimingsBase::begin () {
|
|
|
|
progress = 0;
|
|
|
|
setState (state_began);
|
|
|
|
if (target)
|
|
|
|
target->begin ();
|
|
|
|
if (duration > 0) {
|
|
|
|
steps = duration; // 10/s updates
|
|
|
|
update_timer = document ()->setTimeout (this, 100); // 50ms
|
|
|
|
curr_step = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::TimingsBase::update (int percentage) {
|
|
|
|
progress = percentage;
|
|
|
|
Node * p = parentNode ().ptr ();
|
|
|
|
if (p->id == RP::id_node_imfl)
|
|
|
|
static_cast <RP::Imfl *> (p)->repaint ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::TimingsBase::finish () {
|
|
|
|
progress = 100;
|
|
|
|
if (start_timer) {
|
|
|
|
document ()->cancelTimer (start_timer);
|
|
|
|
start_timer = 0;
|
|
|
|
} else if (duration_timer) {
|
|
|
|
document ()->cancelTimer (duration_timer);
|
|
|
|
duration_timer = 0;
|
|
|
|
}
|
|
|
|
if (update_timer) {
|
|
|
|
document ()->cancelTimer (update_timer);
|
|
|
|
update_timer = 0;
|
|
|
|
}
|
|
|
|
document_postponed = 0L; // disconnect
|
|
|
|
Element::finish ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Crossfade::activate () {
|
|
|
|
TimingsBase::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Crossfade::begin () {
|
|
|
|
//kdDebug () << "RP::Crossfade::begin" << endl;
|
|
|
|
TimingsBase::begin ();
|
|
|
|
if (target && target->id == id_node_image) {
|
|
|
|
RP::Image * img = static_cast <RP::Image *> (target.ptr ());
|
|
|
|
if (!img->isReady (true))
|
|
|
|
document_postponed = document()->connectTo (this, event_postponed);
|
|
|
|
else
|
|
|
|
update (duration > 0 ? 0 : 100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Crossfade::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fadein::activate () {
|
|
|
|
// pickup color from Fill that should be declared before this node
|
|
|
|
from_color = 0;
|
|
|
|
TimingsBase::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fadein::begin () {
|
|
|
|
//kdDebug () << "RP::Fadein::begin" << endl;
|
|
|
|
TimingsBase::begin ();
|
|
|
|
if (target && target->id == id_node_image) {
|
|
|
|
RP::Image * img = static_cast <RP::Image *> (target.ptr ());
|
|
|
|
if (!img->isReady (true))
|
|
|
|
document_postponed = document()->connectTo (this, event_postponed);
|
|
|
|
else
|
|
|
|
update (duration > 0 ? 0 : 100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fadein::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fadeout::activate () {
|
|
|
|
to_color = TQColor (getAttribute ("color")).rgb ();
|
|
|
|
TimingsBase::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fadeout::begin () {
|
|
|
|
//kdDebug () << "RP::Fadeout::begin" << endl;
|
|
|
|
TimingsBase::begin ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fadeout::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fill::activate () {
|
|
|
|
color = TQColor (getAttribute ("color")).rgb ();
|
|
|
|
TimingsBase::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fill::begin () {
|
|
|
|
setState (state_began);
|
|
|
|
update (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Fill::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Wipe::activate () {
|
|
|
|
//TODO implement 'type="push"'
|
|
|
|
TQString dir = getAttribute ("direction").lower ();
|
|
|
|
direction = dir_right;
|
|
|
|
if (dir == TQString::fromLatin1 ("left"))
|
|
|
|
direction = dir_left;
|
|
|
|
else if (dir == TQString::fromLatin1 ("up"))
|
|
|
|
direction = dir_up;
|
|
|
|
else if (dir == TQString::fromLatin1 ("down"))
|
|
|
|
direction = dir_down;
|
|
|
|
TimingsBase::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Wipe::begin () {
|
|
|
|
//kdDebug () << "RP::Wipe::begin" << endl;
|
|
|
|
TimingsBase::begin ();
|
|
|
|
if (target && target->id == id_node_image) {
|
|
|
|
RP::Image * img = static_cast <RP::Image *> (target.ptr ());
|
|
|
|
if (!img->isReady (true))
|
|
|
|
document_postponed = document()->connectTo (this, event_postponed);
|
|
|
|
else
|
|
|
|
update (duration > 0 ? 0 : 100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::Wipe::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::ViewChange::activate () {
|
|
|
|
TimingsBase::activate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::ViewChange::begin () {
|
|
|
|
kdDebug () << "RP::ViewChange::begin" << endl;
|
|
|
|
setState (state_began);
|
|
|
|
Node * p = parentNode ().ptr ();
|
|
|
|
if (p->id == RP::id_node_imfl)
|
|
|
|
static_cast <RP::Imfl *> (p)->needs_scene_img++;
|
|
|
|
update (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::ViewChange::finish () {
|
|
|
|
Node * p = parentNode ().ptr ();
|
|
|
|
if (p && p->id == RP::id_node_imfl)
|
|
|
|
static_cast <RP::Imfl *> (p)->needs_scene_img--;
|
|
|
|
TimingsBase::finish ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void RP::ViewChange::accept (Visitor * v) {
|
|
|
|
v->visit (this);
|
|
|
|
}
|