Fix corruption when changing the project profile

svn path=/trunk/kdenlive/; revision=3886
parent 9cee0c08
......@@ -185,6 +185,13 @@ double AbstractClipItem::fps() const
return m_fps;
}
void AbstractClipItem::updateFps(double fps)
{
m_fps = fps;
setPos((qreal) startPos().frames(m_fps), pos().y());
updateRectGeometry();
}
GenTime AbstractClipItem::maxDuration() const
{
return m_maxDuration;
......
......@@ -57,6 +57,7 @@ public:
virtual void resizeStart(int posx, double speed = 1.0);
virtual void resizeEnd(int posx, double speed = 1.0);
virtual double fps() const;
virtual void updateFps(double fps);
virtual GenTime maxDuration() const;
virtual void setCropStart(GenTime pos);
......
......@@ -1000,13 +1000,11 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup)
}
QList<QGraphicsItem *> selection = m_scene->selectedItems();
if (selection.isEmpty()) return;
QPointF top = selection.at(0)->sceneBoundingRect().topLeft();
QRectF rectUnion;
// Find top left position of selection
for (int i = 1; i < selection.count(); i++) {
for (int i = 0; i < selection.count(); i++) {
if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET) {
QPointF currenttop = selection.at(i)->sceneBoundingRect().topLeft();
if (currenttop.x() < top.x()) top.setX(currenttop.x());
if (currenttop.y() < top.y()) top.setY(currenttop.y());
rectUnion = rectUnion.united(selection.at(i)->sceneBoundingRect());
}
}
......@@ -1015,8 +1013,8 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup)
KdenliveSettings::setSnaptopoints(false);
if (createNewGroup) {
AbstractGroupItem *newGroup = m_document->clipManager()->createGroup();
newGroup->translate(-top.x(), -top.y() + 1);
newGroup->setPos(top.x(), top.y() - 1);
newGroup->translate(-rectUnion.left(), -rectUnion.top() + 1);
newGroup->setPos(rectUnion.left(), rectUnion.top() - 1);
scene()->addItem(newGroup);
// CHeck if we are trying to include a group in a group
......@@ -1045,8 +1043,8 @@ void CustomTrackView::groupSelectedItems(bool force, bool createNewGroup)
KdenliveSettings::setSnaptopoints(snap);
} else {
m_selectionGroup = new AbstractGroupItem(m_document->fps());
m_selectionGroup->translate(-top.x(), -top.y() + 1);
m_selectionGroup->setPos(top.x(), top.y() - 1);
m_selectionGroup->translate(-rectUnion.left(), -rectUnion.top() + 1);
m_selectionGroup->setPos(rectUnion.left(), rectUnion.top() - 1);
scene()->addItem(m_selectionGroup);
for (int i = 0; i < selection.count(); i++) {
if (selection.at(i)->parentItem() == NULL && (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET || selection.at(i)->type() == GROUPWIDGET)) {
......@@ -3413,8 +3411,10 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
ClipItem *clip = getClipItemAt(startClip.at(i).startPos, startClip.at(i).track);
if (clip) {
clip->setItemLocked(false);
if (clip->parentItem()) clip->parentItem()->setSelected(true);
else clip->setSelected(true);
if (clip->parentItem()) {
clip->parentItem()->setSelected(true);
}
clip->setSelected(true);
m_document->renderer()->mltRemoveClip(m_document->tracksCount() - startClip.at(i).track, startClip.at(i).startPos);
} else kDebug() << "//MISSING CLIP AT: " << startClip.at(i).startPos.frames(25);
}
......@@ -3426,8 +3426,9 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
Transition *tr = getTransitionItemAt(startTransition.at(i).startPos, startTransition.at(i).track);
if (tr) {
tr->setItemLocked(false);
if (tr->parentItem()) tr->parentItem()->setSelected(true);
else tr->setSelected(true);
if (tr->parentItem()) {
tr->parentItem()->setSelected(true);
} else tr->setSelected(true);
m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_document->tracksCount() - startTransition.at(i).track, startTransition.at(i).startPos, startTransition.at(i).endPos, tr->toXML());
} else kDebug() << "//MISSING TRANSITION AT: " << startTransition.at(i).startPos.frames(25);
}
......@@ -3445,6 +3446,12 @@ void CustomTrackView::moveGroup(QList <ItemInfo> startClip, QList <ItemInfo> sta
for (int i = 0; i < max; i++) {
if (children.at(i)->type() == GROUPWIDGET) {
children += children.at(i)->childItems();
AbstractGroupItem *grp = static_cast<AbstractGroupItem *>(children.at(i));
//grp->moveBy(offset.frames(m_document->fps()), trackOffset *(qreal) m_tracksHeight);
/*m_document->clipManager()->removeGroup(grp);
m_scene->destroyItemGroup(grp);*/
children.removeAll(children.at(i));
i--;
}
}
......@@ -3860,7 +3867,7 @@ bool CustomTrackView::addGuide(const GenTime pos, const QString &comment)
return false;
}
}
Guide *g = new Guide(this, pos, comment, m_document->fps(), m_tracksHeight * m_document->tracksCount());
Guide *g = new Guide(this, pos, comment, m_tracksHeight * m_document->tracksCount());
scene()->addItem(g);
m_guides.append(g);
qSort(m_guides.begin(), m_guides.end(), sortGuidesList);
......@@ -4931,4 +4938,54 @@ void CustomTrackView::reloadTransitionLumas()
emit transitionItemSelected(NULL);
}
#include "customtrackview.moc"
double CustomTrackView::fps() const
{
return m_document->fps();
}
void CustomTrackView::updateProjectFps()
{
// update all clips to the new fps
resetSelectionGroup();
scene()->clearSelection();
m_dragItem = NULL;
QList<QGraphicsItem *> itemList = items();
for (int i = 0; i < itemList.count(); i++) {
// remove all items and re-add them one by one
if (itemList.at(i) != m_cursorLine && itemList.at(i)->parentItem() == NULL) m_scene->removeItem(itemList.at(i));
}
for (int i = 0; i < itemList.count(); i++) {
if (itemList.at(i)->parentItem() == 0 && (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET)) {
AbstractClipItem *clip = static_cast <AbstractClipItem *>(itemList.at(i));
clip->updateFps(m_document->fps());
m_scene->addItem(clip);
} else if (itemList.at(i)->type() == GROUPWIDGET) {
AbstractGroupItem *grp = static_cast <AbstractGroupItem *>(itemList.at(i));
QList<QGraphicsItem *> children = grp->childItems();
for (int j = 0; j < children.count(); j++) {
if (children.at(j)->type() == AVWIDGET || children.at(j)->type() == TRANSITIONWIDGET) {
AbstractClipItem *clip = static_cast <AbstractClipItem *>(children.at(j));
clip->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
clip->updateFps(m_document->fps());
}
}
m_document->clipManager()->removeGroup(grp);
m_scene->addItem(grp);
scene()->destroyItemGroup(grp);
for (int j = 0; j < children.count(); j++) {
if (children.at(j)->type() == AVWIDGET || children.at(j)->type() == TRANSITIONWIDGET) {
//children.at(j)->setParentItem(0);
children.at(j)->setSelected(true);
}
}
groupSelectedItems(true, true);
} else if (itemList.at(i)->type() == GUIDEITEM) {
Guide *g = static_cast<Guide *>(itemList.at(i));
g->updatePos();
m_scene->addItem(g);
}
}
viewport()->update();
}
#include "customtrackview.moc"
\ No newline at end of file
......@@ -122,6 +122,8 @@ public:
void doChangeClipType(const GenTime &pos, int track, bool videoOnly, bool audioOnly);
int hasGuide(int pos, int offset);
void reloadTransitionLumas();
void updateProjectFps();
double fps() const;
public slots:
void setCursorPos(int pos, bool seek = true);
......
......@@ -155,8 +155,7 @@ void DocumentChecker::slotSearchClips()
child->setIcon(0, KIcon("dialog-ok"));
child->setData(0, statusRole, CLIPOK);
}
}
else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
} else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
QString fileName = searchLuma(child->data(0, idRole).toString());
if (!fileName.isEmpty()) {
child->setText(1, fileName);
......@@ -248,7 +247,7 @@ void DocumentChecker::accept()
// prepare transitions
QDomNodeList trans = m_doc.elementsByTagName("transition");
QTreeWidgetItem *child = treeWidget->topLevelItem(ix);
while (child) {
if (child->data(0, statusRole).toInt() == CLIPOK) {
......@@ -290,10 +289,10 @@ void DocumentChecker::accept()
} else if (child->data(0, statusRole).toInt() == LUMAOK) {
for (int i = 0; i < trans.count(); i++) {
QString luma = getProperty(trans.at(i).toElement(), "luma");
kDebug()<< "luma: "<<luma;
kDebug() << "luma: " << luma;
if (!luma.isEmpty() && luma == child->data(0, idRole).toString()) {
setProperty(trans.at(i).toElement(), "luma", child->text(1));
kDebug()<< "replace with; "<<child->text(1);
kDebug() << "replace with; " << child->text(1);
}
}
} else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
......@@ -318,8 +317,7 @@ void DocumentChecker::slotPlaceholders()
if (child->data(0, statusRole).toInt() == CLIPMISSING) {
child->setData(0, statusRole, CLIPPLACEHOLDER);
child->setIcon(0, KIcon("dialog-ok"));
}
else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
} else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
child->setData(0, statusRole, LUMAPLACEHOLDER);
child->setIcon(0, KIcon("dialog-ok"));
}
......
......@@ -27,18 +27,17 @@
#include <QBrush>
#include <QStyleOptionGraphicsItem>
Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height) :
Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double height) :
QGraphicsLineItem(),
m_position(pos),
m_label(label),
m_fps(fps),
m_view(view),
m_pen(QPen())
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIgnoresTransformations);
setToolTip(label);
setLine(0, 0, 0, height);
setPos(m_position.frames(m_fps), 0);
setPos(m_position.frames(m_view->fps()), 0);
m_pen.setWidthF(0);
m_pen.setColor(QColor(0, 0, 200, 180));
//m_pen.setCosmetic(true);
......@@ -68,7 +67,7 @@ CommentedTime Guide::info() const
void Guide::updateGuide(const GenTime newPos, const QString &comment)
{
m_position = newPos;
setPos(m_position.frames(m_fps), 0);
setPos(m_position.frames(m_view->fps()), 0);
if (!comment.isEmpty()) {
m_label = comment;
setToolTip(m_label);
......@@ -78,6 +77,11 @@ void Guide::updateGuide(const GenTime newPos, const QString &comment)
}
}
void Guide::updatePos()
{
setPos(m_position.frames(m_view->fps()), 0);
}
//virtual
int Guide::type() const
{
......
......@@ -34,11 +34,12 @@ class Guide : public QGraphicsLineItem
{
public:
Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height);
Guide(CustomTrackView *view, GenTime pos, QString label, double height);
GenTime position() const;
void updateGuide(const GenTime newPos, const QString &comment = QString());
QString label() const;
CommentedTime info() const;
void updatePos();
virtual int type() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w);
virtual QRectF boundingRect() const;
......@@ -52,7 +53,6 @@ protected:
private:
GenTime m_position;
QString m_label;
double m_fps;
CustomTrackView *m_view;
int m_width;
QPen m_pen;
......
......@@ -81,6 +81,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
success = m_document.setContent(&file, false, &errorMsg);
file.close();
KIO::NetAccess::removeTempFile(tmpFile);
if (!success) // It is corrupted
KMessageBox::error(parent, errorMsg);
else {
......@@ -260,14 +261,8 @@ int KdenliveDoc::setSceneList()
return 0;
}
QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int audiotracks)
QDomDocument KdenliveDoc::createEmptyDocument(int videotracks, int audiotracks)
{
// Creating new document
QDomDocument doc;
QDomElement mlt = doc.createElement("mlt");
doc.appendChild(mlt);
TrackInfo videoTrack;
videoTrack.type = VIDEOTRACK;
videoTrack.isMute = false;
......@@ -280,6 +275,25 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a
audioTrack.isBlind = true;
audioTrack.isLocked = false;
m_tracksList.clear();
for (int i = 0; i < audiotracks; i++) {
m_tracksList.append(audioTrack);
}
for (int i = 0; i < videotracks; i++) {
m_tracksList.append(videoTrack);
}
return createEmptyDocument(m_tracksList);
}
QDomDocument KdenliveDoc::createEmptyDocument(QList <TrackInfo> tracks)
{
// Creating new document
QDomDocument doc;
QDomElement mlt = doc.createElement("mlt");
doc.appendChild(mlt);
// Create black producer
// For some unknown reason, we have to build the black producer here and not in renderer.cpp, otherwise
// the composite transitions with the black track are corrupted.
......@@ -341,7 +355,7 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a
playlist.appendChild(blank0);
// create playlists
int total = audiotracks + videotracks + 1;
int total = tracks.count() + 1;
for (int i = 1; i < total; i++) {
QDomElement playlist = doc.createElement("playlist");
......@@ -354,20 +368,16 @@ QDomDocument KdenliveDoc::createEmptyDocument(const int videotracks, const int a
tractor.appendChild(track0);
// create audio tracks
for (int i = 1; i < audiotracks + 1; i++) {
QDomElement track = doc.createElement("track");
track.setAttribute("producer", "playlist" + QString::number(i));
track.setAttribute("hide", "video");
tractor.appendChild(track);
m_tracksList.append(audioTrack);
}
// create video tracks
for (int i = audiotracks + 1; i < total; i++) {
for (int i = 1; i < total; i++) {
QDomElement track = doc.createElement("track");
track.setAttribute("producer", "playlist" + QString::number(i));
if (tracks.at(i - 1).type == AUDIOTRACK)
track.setAttribute("hide", "video");
else if (tracks.at(i - 1).isBlind)
track.setAttribute("hide", "video");
if (tracks.at(i - 1).isMute)
track.setAttribute("hide", "audio");
tractor.appendChild(track);
m_tracksList.append(videoTrack);
}
for (int i = 2; i < total ; i++) {
......@@ -640,11 +650,12 @@ MltVideoProfile KdenliveDoc::mltProfile() const
return m_profile;
}
void KdenliveDoc::setProfilePath(QString path)
bool KdenliveDoc::setProfilePath(QString path)
{
if (path.isEmpty()) path = KdenliveSettings::default_profile();
if (path.isEmpty()) path = "dv_pal";
m_profile = ProfilesDialog::getVideoProfile(path);
bool current_fps = m_fps;
if (m_profile.path.isEmpty()) {
// Profile not found, use embedded profile
QDomElement profileInfo = m_document.elementsByTagName("profileinfo").at(0).toElement();
......@@ -697,6 +708,7 @@ void KdenliveDoc::setProfilePath(QString path)
kDebug() << "Kdenlive document, init timecode from path: " << path << ", " << m_fps;
if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(m_fps, true);
else m_timecode.setFormat(m_fps);
return (current_fps != m_fps);
}
double KdenliveDoc::dar()
......
......@@ -81,7 +81,8 @@ Q_OBJECT public:
MltVideoProfile mltProfile() const;
const QString description() const;
void setUrl(KUrl url);
void setProfilePath(QString path);
/** update project profile, returns true if fps was changed */
bool setProfilePath(QString path);
const QString getFreeClipId();
/** does the document need saving */
bool isModified() const;
......@@ -139,13 +140,12 @@ private:
QMap <QString, QString> m_documentProperties;
QList <TrackInfo> m_tracksList;
QDomDocument createEmptyDocument(const int videotracks, const int audiotracks);
void setNewClipResource(const QString &id, const QString &path);
QString searchFileRecursively(const QDir &dir, const QString &matchSize, const QString &matchHash) const;
void moveProjectData(KUrl url);
bool checkDocumentClips(QDomNodeList infoproducers);
QDomDocument createEmptyDocument(int videotracks, int audiotracks);
QDomDocument createEmptyDocument(QList <TrackInfo> tracks);
public slots:
void slotCreateColorClip(const QString &name, const QString &color, const QString &duration, QString group, const QString &groupId);
......
......@@ -684,7 +684,7 @@ void MainWindow::setupActions()
m_statusProgressBar->setMaximumWidth(150);
m_statusProgressBar->setVisible(false);
KToolBar *toolbar = new KToolBar("statusToolBar", this, Qt::BottomToolBarArea);
KToolBar *toolbar = new KToolBar("statusToolBar", this, Qt::BottomToolBarArea);
toolbar->setMovable(false);
m_toolGroup = new QActionGroup(this);
statusBar()->setStyleSheet(QString("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize()));
......@@ -1627,7 +1627,7 @@ void MainWindow::slotEditProjectSettings()
m_effectStack->slotClipItemSelected(NULL, 0);
m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false);
m_clipMonitor->slotSetXml(NULL, 0);
m_activeDocument->setProfilePath(profile);
bool updateFps = m_activeDocument->setProfilePath(profile);
KdenliveSettings::setCurrent_profile(profile);
KdenliveSettings::setProject_fps(m_activeDocument->fps());
setCaption(m_activeDocument->description(), m_activeDocument->isModified());
......@@ -1641,7 +1641,7 @@ void MainWindow::slotEditProjectSettings()
m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
//m_activeDocument->clipManager()->resetProducersList(m_projectMonitor->render->producersList());
if (dar != m_activeDocument->dar()) m_projectList->reloadClipThumbnails();
m_activeTimeline->updateProjectFps();
if (updateFps) m_activeTimeline->updateProjectFps();
// We need to desactivate & reactivate monitors to get a refresh
//m_monitorManager->switchMonitors();
......
......@@ -116,12 +116,15 @@ void Render::closeMlt()
Mlt::Tractor tractor(service);
Mlt::Field *field = tractor.field();
mlt_service nextservice = mlt_service_get_producer(service.get_service());
mlt_service nextservicetodisconnect;
mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
QString mlt_type = mlt_properties_get(properties, "mlt_type");
QString resource = mlt_properties_get(properties, "mlt_service");
// Delete all transitions
while (mlt_type == "transition") {
mlt_field_disconnect_service(field->get_field(), nextservice);
nextservicetodisconnect = nextservice;
nextservice = mlt_service_producer(nextservice);
mlt_field_disconnect_service(field->get_field(), nextservicetodisconnect);
nextservice = mlt_service_producer(nextservice);
if (nextservice == NULL) break;
properties = MLT_SERVICE_PROPERTIES(nextservice);
......@@ -244,7 +247,7 @@ int Render::resetProfile()
m_mltConsumer = NULL;
QString scene = sceneList();
int pos = 0;
double current_fps = m_mltProfile->fps();
delete m_blackClip;
m_blackClip = NULL;
......@@ -268,7 +271,11 @@ int Render::resetProfile()
m_mltProducer = NULL;
buildConsumer();
double new_fps = m_mltProfile->fps();
if (current_fps != new_fps) {
// fps changed, we must update the scenelist positions
scene = updateSceneListFps(current_fps, new_fps, scene);
}
//kDebug() << "//RESET WITHSCENE: " << scene;
setSceneList(scene, pos);
......@@ -927,13 +934,15 @@ int Render::setSceneList(QString playlist, int position)
Mlt::Tractor tractor(service);
Mlt::Field *field = tractor.field();
mlt_service nextservice = mlt_service_get_producer(service.get_service());
mlt_service nextservicetodisconnect;
mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
QString mlt_type = mlt_properties_get(properties, "mlt_type");
QString resource = mlt_properties_get(properties, "mlt_service");
// Delete all transitions
while (mlt_type == "transition") {
mlt_field_disconnect_service(field->get_field(), nextservice);
nextservicetodisconnect = nextservice;
nextservice = mlt_service_producer(nextservice);
mlt_field_disconnect_service(field->get_field(), nextservicetodisconnect);
if (nextservice == NULL) break;
properties = MLT_SERVICE_PROPERTIES(nextservice);
mlt_type = mlt_properties_get(properties, "mlt_type");
......@@ -3351,5 +3360,100 @@ void Render::updatePreviewSettings()
setSceneList(scene, pos);
}
QString Render::updateSceneListFps(double current_fps, double new_fps, QString scene)
{
// Update all frame positions to the new fps value
//WARNING: there are probably some effects or other that hold a frame value
// as parameter and will also need to be updated here!
QDomDocument doc;
doc.setContent(scene);
double factor = new_fps / current_fps;
QDomNodeList producers = doc.elementsByTagName("producer");
for (int i = 0; i < producers.count(); i++) {
QDomElement prod = producers.at(i).toElement();
prod.removeAttribute("in");
prod.removeAttribute("out");
QDomNodeList props = prod.childNodes();
for (int j = 0; j < props.count(); j++) {
QDomElement param = props.at(j).toElement();
QString paramName = param.attribute("name");
if (paramName.startsWith("meta.") || paramName == "length") {
prod.removeChild(props.at(j));
j--;
}
}
}
QDomNodeList entries = doc.elementsByTagName("entry");
for (int i = 0; i < entries.count(); i++) {
QDomElement entry = entries.at(i).toElement();
int in = entry.attribute("in").toInt();
int out = entry.attribute("out").toInt();
in = factor * in + 0.5;
out = factor * out + 0.5;
entry.setAttribute("in", in);
entry.setAttribute("out", out);
}
QDomNodeList blanks = doc.elementsByTagName("blank");
for (int i = 0; i < blanks.count(); i++) {
QDomElement blank = blanks.at(i).toElement();
int length = blank.attribute("length").toInt();
length = factor * length + 0.5;
blank.setAttribute("length", QString::number(length));
}
QDomNodeList filters = doc.elementsByTagName("filter");
for (int i = 0; i < filters.count(); i++) {
QDomElement filter = filters.at(i).toElement();
int in = filter.attribute("in").toInt();
int out = filter.attribute("out").toInt();
in = factor * in + 0.5;
out = factor * out + 0.5;
filter.setAttribute("in", in);
filter.setAttribute("out", out);
}
QDomNodeList transitions = doc.elementsByTagName("transition");
for (int i = 0; i < transitions.count(); i++) {
QDomElement transition = transitions.at(i).toElement();
int in = transition.attribute("in").toInt();
int out = transition.attribute("out").toInt();
in = factor * in + 0.5;
out = factor * out + 0.5;
transition.setAttribute("in", in);
transition.setAttribute("out", out);
QDomNodeList props = transition.childNodes();
for (int j = 0; j < props.count(); j++) {
QDomElement param = props.at(j).toElement();
QString paramName = param.attribute("name");
if (paramName == "geometry") {
QString geom = param.firstChild().nodeValue();
QStringList keys = geom.split(';');
QStringList newKeys;
for (int k = 0; k < keys.size(); ++k) {
if (keys.at(k).contains('=')) {
int pos = keys.at(k).section('=', 0, 0).toInt();
pos = factor * pos + 0.5;
newKeys.append(QString::number(pos) + '=' + keys.at(k).section('=', 1));
} else newKeys.append(keys.at(k));
}
param.firstChild().setNodeValue(newKeys.join(";"));
}
}
}
QDomElement tractor = doc.elementsByTagName("tractor").at(0).toElement();
int out = tractor.attribute("out").toInt();
out = factor * out + 0.5;
tractor.setAttribute("out", out);
emit durationChanged(out);
kDebug() << "///////////////////////////// " << out << " \n" << doc.toString() << "\n-------------------------";
return doc.toString();
}
#include "renderer.moc"