From: Ed Rogalsky Date: Thu, 25 Oct 2012 21:09:17 +0000 (+0200) Subject: Merge branch 'master' into feature/pkey X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=71e41ad0c197e2e2eb033dff7800427f64d3428f;hp=e5bed1802f629406c47711f2a6e26f7c0286b11f;p=kdenlive Merge branch 'master' into feature/pkey --- diff --git a/effects/automask.xml b/effects/automask.xml index aa471472..ae68503a 100644 --- a/effects/automask.xml +++ b/effects/automask.xml @@ -6,13 +6,19 @@ Geometry - + Macroblock width - + Macroblock height - + + Maximum x distance + + + Maximum y distance + + Denoise @@ -21,7 +27,12 @@ Obscure - + + + + motion_vector_list + autotrack_rectangle + Motion vectors Analyse diff --git a/effects/sox_gain.xml b/effects/sox_gain.xml index 0a67a674..11f7a8db 100644 --- a/effects/sox_gain.xml +++ b/effects/sox_gain.xml @@ -6,7 +6,9 @@ Gain - + + gain + sox_gain Normalize diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 091eee6a..6553c6bd 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -1145,7 +1145,7 @@ void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, in int sample = (int)((frame - (int)(frame)) * 20); // AUDIO_FRAME_SIZE if (frame < 0 || sample < 0 || sample > 19) continue; - QMap frame_channel_data = baseClip()->m_audioFrameCache[(int)frame]; + QMap frame_channel_data = baseClip()->audioFrameCache[(int)frame]; for (int channel = 0; channel < channels && frame_channel_data[channel].size() > 0; channel++) { diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index c6552696..a706e5ad 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -26,6 +26,7 @@ #include "abstractclipitem.h" #include "abstractgroupitem.h" #include "titledocument.h" +#include "subprojectitem.h" #include "kthumb.h" #include @@ -167,19 +168,42 @@ void ClipManager::slotGetThumbs() QMap::const_iterator i; int max; int done = 0; + int thumbType = 0; // 0 = timeline thumb, 1 = project clip zone thumb, 2 = clip properties thumb + while (!m_requestedThumbs.isEmpty() && !m_abortThumb) { m_thumbsMutex.lock(); i = m_requestedThumbs.constBegin(); m_processingThumbId = i.key(); QList values = m_requestedThumbs.values(m_processingThumbId); m_requestedThumbs.remove(m_processingThumbId); + if (m_processingThumbId.startsWith("?")) { + // if id starts with ?, it means the request comes from a clip property widget + thumbType = 2; + m_processingThumbId.remove(0, 1); + } + if (m_processingThumbId.startsWith("#")) { + // if id starts with #, it means the request comes from project tree + thumbType = 1; + m_processingThumbId.remove(0, 1); + } m_thumbsMutex.unlock(); qSort(values); DocClipBase *clip = getClipById(m_processingThumbId); if (!clip) continue; max = m_requestedThumbs.size() + values.count(); + int pos; while (!values.isEmpty() && clip->thumbProducer() && !m_abortThumb) { - clip->thumbProducer()->getThumb(values.takeFirst()); + pos = values.takeFirst(); + switch (thumbType) { + case 1: + clip->thumbProducer()->getGenericThumb(pos, SubProjectItem::itemDefaultHeight(), thumbType); + break; + case 2: + clip->thumbProducer()->getGenericThumb(pos, 180, thumbType); + break; + default: + clip->thumbProducer()->getThumb(pos); + } done++; if (max > 3) emit displayMessage(i18n("Loading thumbnails"), 100 * done / max); } @@ -918,5 +942,14 @@ bool ClipManager::isOnRemovableDevice(const KUrl &url) return volumeMatch; } - +void ClipManager::projectTreeThumbReady(const QString &id, int frame, QImage img, int type) +{ + switch (type) { + case 2: + emit gotClipPropertyThumbnail(id, img); + break; + default: + emit thumbReady(id, frame, img); + } +} diff --git a/src/clipmanager.h b/src/clipmanager.h index 512edd20..ca85ab05 100644 --- a/src/clipmanager.h +++ b/src/clipmanager.h @@ -127,6 +127,7 @@ Q_OBJECT public: void requestThumbs(const QString id, QList frames); /** @brief remove a clip id from the queue list. */ void stopThumbs(const QString &id); + void projectTreeThumbReady(const QString &id, int frame, QImage img, int type); #if KDE_IS_VERSION(4,5,0) KImageCache* pixmapCache; @@ -177,6 +178,8 @@ private: // Private attributes QString m_processingAudioThumbId; /** @brief The list of removable drives. */ QList m_removableVolumes; + + QPoint m_projectTreeThumbSize; /** @brief Get a list of drives, to check if we have files on removable media. */ void listRemovableVolumes(); @@ -190,6 +193,8 @@ signals: void availableClip(const QString &); void checkAllClips(bool displayRatioChanged, bool fpsChanged, QStringList brokenClips); void displayMessage(const QString &, int); + void thumbReady(const QString &id, int, QImage); + void gotClipPropertyThumbnail(const QString &id, QImage); }; #endif diff --git a/src/clipproperties.cpp b/src/clipproperties.cpp index 1d5e39ee..22bc7269 100644 --- a/src/clipproperties.cpp +++ b/src/clipproperties.cpp @@ -435,21 +435,8 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg if (props.contains("colorspace")) new QTreeWidgetItem(m_view.clip_vproperties, QStringList() << i18n("Colorspace") << ProfilesDialog::getColorspaceDescription(props.value("colorspace").toInt())); - - int width = 180.0 * KdenliveSettings::project_display_ratio(); - if (width % 2 == 1) width++; - QPixmap pix = m_clip->thumbProducer()->getImage(url, m_clip->getClipThumbFrame(), width, 180); - QPixmap framedPix(pix.width(), pix.height()); - framedPix.fill(Qt::transparent); - QPainter p(&framedPix); - p.setRenderHint(QPainter::Antialiasing, true); - QPainterPath path; - path.addRoundedRect(0.5, 0.5, framedPix.width() - 1, framedPix.height() - 1, 4, 4); - p.setClipPath(path); - p.drawPixmap(0, 0, pix); - p.end(); - - m_view.clip_thumb->setPixmap(framedPix); + m_view.clip_thumb->setMinimumSize(180 * KdenliveSettings::project_display_ratio(), 180); + if (t == IMAGE || t == VIDEO || t == PLAYLIST) m_view.tabWidget->removeTab(AUDIOTAB); } else { m_view.tabWidget->removeTab(IMAGETAB); @@ -688,6 +675,21 @@ ClipProperties::~ClipProperties() if (del2) delete del2; } +void ClipProperties::slotGotThumbnail(const QString &id, QImage img) +{ + if (id != m_clip->getId()) return; + QPixmap framedPix(img.width(), img.height()); + framedPix.fill(Qt::transparent); + QPainter p(&framedPix); + p.setRenderHint(QPainter::Antialiasing, true); + QPainterPath path; + path.addRoundedRect(0.5, 0.5, framedPix.width() - 1, framedPix.height() - 1, 4, 4); + p.setClipPath(path); + p.drawImage(0, 0, img); + p.end(); + m_view.clip_thumb->setPixmap(framedPix); +} + void ClipProperties::slotApplyProperties() { if (m_clip != NULL) { diff --git a/src/clipproperties.h b/src/clipproperties.h index ec0dee89..18ef15fd 100644 --- a/src/clipproperties.h +++ b/src/clipproperties.h @@ -76,6 +76,7 @@ private slots: void slotSaveMarkers(); void slotLoadMarkers(); void slotDeleteAnalysis(); + void slotGotThumbnail(const QString &id, QImage img); private: Ui::ClipProperties_UI m_view; diff --git a/src/customruler.cpp b/src/customruler.cpp index 1a32d778..82485665 100644 --- a/src/customruler.cpp +++ b/src/customruler.cpp @@ -59,7 +59,8 @@ CustomRuler::CustomRuler(Timecode tc, CustomTrackView *parent) : m_lastSeekPosition(SEEK_INACTIVE), m_clickedGuide(-1), m_rate(-1), - m_mouseMove(NO_MOVE) + m_mouseMove(NO_MOVE), + m_cursorColor(palette().text()) { setFont(KGlobalSettings::toolBarFont()); QFontMetricsF fontMetrics(font()); @@ -216,7 +217,17 @@ void CustomRuler::mouseMoveEvent(QMouseEvent * event) update(min * m_factor - m_offset - 2, 0, (max - min) * m_factor + 4, height()); } else { - int pos = (int)((event->x() + offset())); + int pos = (int)((event->x() + m_offset)); + if (m_cursorColor == palette().text() && qAbs(pos - m_view->cursorPos() * m_factor) < 7) { + // Mouse is over cursor + m_cursorColor = palette().highlight(); + update(m_view->cursorPos() * m_factor - m_offset - 10, 0, 20, height()); + } + else if (m_cursorColor == palette().highlight() && qAbs(pos - m_view->cursorPos() * m_factor) >= 7) { + m_cursorColor = palette().text(); + update(m_view->cursorPos() * m_factor - m_offset - 10, 0, 20, height()); + } + if (event->y() <= 10) setCursor(Qt::ArrowCursor); else if (qAbs(pos - m_zoneStart * m_factor) < 4) { setCursor(KCursor("left_side", Qt::SizeHorCursor)); @@ -239,6 +250,16 @@ void CustomRuler::mouseMoveEvent(QMouseEvent * event) } +// virtual +void CustomRuler::leaveEvent(QEvent * event) +{ + QWidget::leaveEvent(event); + if (m_cursorColor == palette().highlight()) { + m_cursorColor = palette().text(); + update(); + } +} + // virtual void CustomRuler::wheelEvent(QWheelEvent * e) { @@ -282,7 +303,7 @@ void CustomRuler::slotCursorMoved(int oldpos, int newpos) max = qMax(max, m_lastSeekPosition); } } - update(min * m_factor - offset() - 6, BIG_MARK_X, (max - min) * m_factor + 14, MAX_HEIGHT - BIG_MARK_X); + update(min * m_factor - m_offset - 6, BIG_MARK_X, (max - min) * m_factor + 14, MAX_HEIGHT - BIG_MARK_X); } void CustomRuler::updateRuler() @@ -461,7 +482,7 @@ void CustomRuler::paintEvent(QPaintEvent *e) const int value = m_view->cursorPos() * m_factor - m_offset; QPolygon pa(3); pa.setPoints(3, value - 6, BIG_MARK_X, value + 6, BIG_MARK_X, value, MAX_HEIGHT - 1); - p.setBrush(palette().text()); + p.setBrush(m_cursorColor); p.setPen(Qt::NoPen); p.drawPolygon(pa); diff --git a/src/customruler.h b/src/customruler.h index da91fb6b..abdc5944 100644 --- a/src/customruler.h +++ b/src/customruler.h @@ -57,6 +57,7 @@ protected: virtual void mousePressEvent(QMouseEvent * event); virtual void mouseReleaseEvent(QMouseEvent * event); virtual void mouseMoveEvent(QMouseEvent * event); + virtual void leaveEvent(QEvent * event); private: Timecode m_timecode; @@ -64,8 +65,6 @@ private: int m_zoneStart; int m_zoneEnd; int m_duration; - QColor m_bgColor; - QColor m_cursorColor; QColor m_zoneColor; double m_textSpacing; double m_factor; @@ -83,6 +82,7 @@ private: int m_startRate; MOUSE_MOVE m_mouseMove; QMenu *m_goMenu; + QBrush m_cursorColor; public slots: diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index de183f87..d03e745d 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -2693,7 +2693,7 @@ void CustomTrackView::dropEvent(QDropEvent * event) groupSelectedItems(true); } else if (items.count() == 1) { m_dragItem = static_cast (items.at(0)); - emit clipItemSelected((ClipItem*)m_dragItem, false); + emit clipItemSelected((ClipItem*) m_dragItem, false); } event->setDropAction(Qt::MoveAction); event->accept(); @@ -7500,16 +7500,16 @@ void CustomTrackView::adjustEffects(ClipItem* item, ItemInfo oldInfo, QUndoComma } -void CustomTrackView::slotGotFilterJobResults(const QString &/*id*/, int startPos, int track, const QString &filter, stringMap filterParams, QStringList extra) +void CustomTrackView::slotGotFilterJobResults(const QString &/*id*/, int startPos, int track, stringMap filterParams, stringMap extra) { ClipItem *clip = getClipItemAt(GenTime(startPos, m_document->fps()), track); if (clip == NULL) { - emit displayMessage(i18n("Cannot find clip for effect update %1.", filter), ErrorMessage); + emit displayMessage(i18n("Cannot find clip for effect update %1.", extra.value("finalfilter")), ErrorMessage); return; } QDomElement newEffect; QDomElement effect = clip->getEffectAtIndex(clip->selectedEffectIndex()); - if (effect.attribute("id") == filter) { + if (effect.attribute("id") == extra.value("finalfilter")) { newEffect = effect.cloneNode().toElement(); QMap::const_iterator i = filterParams.constBegin(); while (i != filterParams.constEnd()) { diff --git a/src/customtrackview.h b/src/customtrackview.h index 7db48f59..bdaa7461 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -497,7 +497,7 @@ private slots: * @param resetThumbs Should we recreate the timeline thumbnails. */ void slotRefreshThumbs(const QString &id, bool resetThumbs); /** @brief A Filter job producer results. */ - void slotGotFilterJobResults(const QString &id, int startPos, int track, const QString &filter, stringMap filterParams, QStringList extra); + void slotGotFilterJobResults(const QString &id, int startPos, int track, stringMap filterParams, stringMap extra); signals: diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index d278eeca..5f2f01a1 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -41,7 +41,8 @@ DocClipBase::DocClipBase(ClipManager *clipManager, QDomElement xml, const QString &id) : QObject(), - m_audioFrameCache(), + lastSeekPosition(0), + audioFrameCache(), m_refcount(0), m_baseTrackProducers(), m_videoTrackProducers(), @@ -137,7 +138,7 @@ bool DocClipBase::hasAudioThumb() const void DocClipBase::slotClearAudioCache() { - m_audioFrameCache.clear(); + audioFrameCache.clear(); m_audioThumbCreated = false; } @@ -284,7 +285,7 @@ void DocClipBase::setAudioThumbCreated(bool isDone) void DocClipBase::updateAudioThumbnail(const audioByteArray& data) { //kDebug() << "CLIPBASE RECIEDVED AUDIO DATA*********************************************"; - m_audioFrameCache = data; + audioFrameCache = data; m_audioThumbCreated = true; emit gotAudioData(); } @@ -1278,7 +1279,18 @@ QImage DocClipBase::extractImage(int frame, int width, int height) void DocClipBase::setAnalysisData(const QString &name, const QString &data) { if (data.isEmpty()) m_analysisdata.remove(name); - else m_analysisdata.insert(name, data); + else { + if (m_analysisdata.contains(name)) { + int i = 1; + QString newname = name + " " + QString::number(i); + while (m_analysisdata.contains(newname)) { + i++; + newname = name + " " + QString::number(i); + } + m_analysisdata.insert(newname, data); + } + else m_analysisdata.insert(name, data); + } } QMap DocClipBase::analysisData() const diff --git a/src/docclipbase.h b/src/docclipbase.h index 724ca218..e6e722c2 100644 --- a/src/docclipbase.h +++ b/src/docclipbase.h @@ -165,10 +165,6 @@ Q_OBJECT public: /** Returns the thumbnail producer used by this clip */ KThumb *thumbProducer(); - /** Cache for every audio Frame with 10 Bytes */ - /** format is frame -> channel ->bytes */ - QMap > m_audioFrameCache; - /** Free cache data */ void slotClearAudioCache(); QString getClipHash() const; @@ -206,9 +202,12 @@ Q_OBJECT public: bool getAudioThumbs(); void setAnalysisData(const QString &name, const QString &data); QMap analysisData() const; + int lastSeekPosition; + /** Cache for every audio Frame with 10 Bytes */ + /** format is frame -> channel ->bytes */ + QMap > audioFrameCache; private: // Private attributes - /** The number of times this clip is used in the project - the number of references to this clip * that exist. */ uint m_refcount; diff --git a/src/dvdwizard.cpp b/src/dvdwizard.cpp index 4cc09174..aa36f604 100644 --- a/src/dvdwizard.cpp +++ b/src/dvdwizard.cpp @@ -294,7 +294,7 @@ void DvdWizard::generateDvd() stream.appendChild(spu); spu.setAttribute("force", "yes"); spu.setAttribute("start", "00:00:00.00"); - spu.setAttribute("image", temp1.fileName()); + //spu.setAttribute("image", temp1.fileName()); spu.setAttribute("select", temp2.fileName()); spu.setAttribute("highlight", temp3.fileName()); /*spu.setAttribute("autoorder", "rows");*/ diff --git a/src/dvdwizardmenu.cpp b/src/dvdwizardmenu.cpp index cc285bda..38ac05a7 100644 --- a/src/dvdwizardmenu.cpp +++ b/src/dvdwizardmenu.cpp @@ -22,12 +22,19 @@ #include #include + +#if KDE_IS_VERSION(4,6,0) +#include +#endif + + #include "kthumb.h" DvdWizardMenu::DvdWizardMenu(const QString &profile, QWidget *parent) : QWizardPage(parent), m_color(NULL), - m_safeRect(NULL) + m_safeRect(NULL), + m_finalSize(720, 576) { m_view.setupUi(this); m_view.play_text->setText(i18n("Play")); @@ -80,15 +87,24 @@ DvdWizardMenu::DvdWizardMenu(const QString &profile, QWidget *parent) : m_safeRect->setPen(pen); m_safeRect->setZValue(5); m_scene->addItem(m_safeRect); - checkBackgroundType(0); - // create menu button DvdButton *button = new DvdButton(m_view.play_text->text()); QFont font = m_view.font_family->currentFont(); font.setPixelSize(m_view.font_size->value()); - font.setStyleStrategy(QFont::NoAntialias); + //font.setStyleStrategy(QFont::NoAntialias); +#if KDE_IS_VERSION(4,6,0) + if (m_view.use_shadow->isChecked()) { + QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); + shadow->setBlurRadius(7); + shadow->setOffset(4, 4); + button->setGraphicsEffect(shadow); + } + connect(m_view.use_shadow, SIGNAL(stateChanged(int)), this, SLOT(slotEnableShadows(int))); +#elif KDE_IS_VERSION(4,6,0) + m_view.use_shadow->setHidden(true); +#endif button->setFont(font); button->setDefaultTextColor(m_view.text_color->color()); button->setZValue(4); @@ -138,8 +154,25 @@ DvdWizardMenu::~DvdWizardMenu() delete m_scene; } -// virtual +void DvdWizardMenu::slotEnableShadows(int enable) +{ +#if KDE_IS_VERSION(4,6,0) + QList list = m_scene->items(); + for (int i = 0; i < list.count(); i++) { + if (list.at(i)->type() == QGraphicsItem::UserType + 1) { + if (enable) { + QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); + shadow->setBlurRadius(7); + shadow->setOffset(4, 4); + list.at(i)->setGraphicsEffect(shadow); + } + else list.at(i)->setGraphicsEffect(NULL); + } + } +#endif +} +// virtual bool DvdWizardMenu::isComplete() const { m_view.error_message->setHidden(true); @@ -286,12 +319,20 @@ void DvdWizardMenu::addButton() DvdButton *button = new DvdButton(m_view.play_text->text()); QFont font = m_view.font_family->currentFont(); font.setPixelSize(m_view.font_size->value()); - font.setStyleStrategy(QFont::NoAntialias); +#if KDE_IS_VERSION(4,6,0) + if (m_view.use_shadow->isChecked()) { + QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); + shadow->setBlurRadius(7); + shadow->setOffset(4, 4); + button->setGraphicsEffect(shadow); + } +#endif + //font.setStyleStrategy(QFont::NoAntialias); button->setFont(font); - button->setDefaultTextColor(m_view.text_color->color()); button->setZValue(4); QRectF r = button->sceneBoundingRect(); m_scene->addItem(button); + updateColor(m_view.text_color->color()); button->setPos((m_width - r.width()) / 2, (m_height - r.height()) / 2); button->setSelected(true); } @@ -311,10 +352,12 @@ void DvdWizardMenu::changeProfile(bool isPal) { m_isPal = isPal; if (isPal == false) { - m_width = 720; + m_finalSize = QSize(720, 480); + m_width = 640; m_height = 480; } else { - m_width = 720; + m_finalSize = QSize(720, 576); + m_width = 768; m_height = 576; } updatePreview(); @@ -431,7 +474,7 @@ void DvdWizardMenu::buildButton() button->setPlainText(m_view.play_text->text()); QFont font = m_view.font_family->currentFont(); font.setPixelSize(m_view.font_size->value()); - font.setStyleStrategy(QFont::NoAntialias); + //font.setStyleStrategy(QFont::NoAntialias); button->setFont(font); button->setDefaultTextColor(m_view.text_color->color()); } @@ -442,6 +485,60 @@ void DvdWizardMenu::updateColor() m_view.menu_preview->viewport()->update(); } +void DvdWizardMenu::prepareUnderLines() +{ + QList list = m_scene->items(); + for (int i = 0; i < list.count(); i++) { + if (list.at(i)->type() == QGraphicsItem::UserType + 1) { + QRectF r = list.at(i)->sceneBoundingRect(); + int bottom = r.bottom() - 1; + if (bottom % 2 == 1) bottom = bottom - 1; + int underlineHeight = r.height() / 10; + if (underlineHeight % 2 == 1) underlineHeight = underlineHeight - 1; + underlineHeight = qMin(underlineHeight, 10); + underlineHeight = qMax(underlineHeight, 2); + r.setTop(bottom - underlineHeight); + r.adjust(2, 0, -2, 0); + QGraphicsRectItem *underline = new QGraphicsRectItem(r); + underline->setData(Qt::UserRole, QString("underline")); + m_scene->addItem(underline); + list.at(i)->setVisible(false); + } + } +} + +void DvdWizardMenu::resetUnderLines() +{ + QList list = m_scene->items(); + QList toDelete; + for (int i = 0; i < list.count(); i++) { + if (list.at(i)->data(Qt::UserRole).toString() == "underline") { + toDelete.append(list.at(i)); + } + if (list.at(i)->type() == QGraphicsItem::UserType + 1) { + list.at(i)->setVisible(true); + } + } + while (!toDelete.isEmpty()) { + QGraphicsItem *item = toDelete.takeFirst(); + delete item; + } +} + +void DvdWizardMenu::updateUnderlineColor(QColor c) +{ + QList list = m_scene->items(); + for (int i = 0; i < list.count(); i++) { + if (list.at(i)->data(Qt::UserRole).toString() == "underline") { + QGraphicsRectItem *underline = static_cast < QGraphicsRectItem* >(list.at(i)); + underline->setPen(Qt::NoPen); + c.setAlpha(150); + underline->setBrush(c); + } + } +} + + void DvdWizardMenu::updateColor(QColor c) { DvdButton *button = NULL; @@ -462,19 +559,20 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2, if (m_safeRect->scene() != 0) m_scene->removeItem(m_safeRect); if (m_color->scene() != 0) m_scene->removeItem(m_color); if (m_background->scene() != 0) m_scene->removeItem(m_background); + prepareUnderLines(); #if QT_VERSION >= 0x040800 - QImage img(m_width, m_height, QImage::Format_ARGB32); + QImage img(m_finalSize.width(), m_finalSize.height(), QImage::Format_ARGB32); img.fill(Qt::transparent); - updateColor(m_view.text_color->color()); + updateUnderlineColor(m_view.text_color->color()); #else - QImage img(m_width, m_height, QImage::Format_Mono); + QImage img(m_finalSize.width(), m_finalSize.height(), QImage::Format_Mono); img.fill(Qt::white); - updateColor(Qt::black); + updateUnderlineColor(Qt::black); #endif QPainter p(&img); - p.setRenderHints(QPainter::Antialiasing, false); - p.setRenderHints(QPainter::TextAntialiasing, false); - m_scene->render(&p, QRectF(0, 0, m_width, m_height)); + //p.setRenderHints(QPainter::Antialiasing, false); + //p.setRenderHints(QPainter::TextAntialiasing, false); + m_scene->render(&p, QRectF(0, 0, m_finalSize.width(), m_finalSize.height()), QRectF(0, 0, m_width, m_height), Qt::IgnoreAspectRatio); p.end(); #if QT_VERSION >= 0x040800 #elif QT_VERSION >= 0x040600 @@ -487,14 +585,14 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2, #if QT_VERSION >= 0x040800 img.fill(Qt::transparent); - updateColor(m_view.highlighted_color->color()); + updateUnderlineColor(m_view.highlighted_color->color()); #else img.fill(Qt::white); #endif p.begin(&img); - p.setRenderHints(QPainter::Antialiasing, false); - p.setRenderHints(QPainter::TextAntialiasing, false); - m_scene->render(&p, QRectF(0, 0, m_width, m_height)); + //p.setRenderHints(QPainter::Antialiasing, false); + //p.setRenderHints(QPainter::TextAntialiasing, false); + m_scene->render(&p, QRectF(0, 0, m_finalSize.width(), m_finalSize.height()), QRectF(0, 0, m_width, m_height), Qt::IgnoreAspectRatio); p.end(); #if QT_VERSION >= 0x040800 #elif QT_VERSION >= 0x040600 @@ -507,14 +605,14 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2, #if QT_VERSION >= 0x040800 img.fill(Qt::transparent); - updateColor(m_view.selected_color->color()); + updateUnderlineColor(m_view.selected_color->color()); #else img.fill(Qt::white); #endif p.begin(&img); - p.setRenderHints(QPainter::Antialiasing, false); - p.setRenderHints(QPainter::TextAntialiasing, false); - m_scene->render(&p, QRectF(0, 0, m_width, m_height)); + //p.setRenderHints(QPainter::Antialiasing, false); + //p.setRenderHints(QPainter::TextAntialiasing, false); + m_scene->render(&p, QRectF(0, 0, m_finalSize.width(), m_finalSize.height()), QRectF(0, 0, m_width, m_height), Qt::IgnoreAspectRatio); p.end(); #if QT_VERSION >= 0x040800 #elif QT_VERSION >= 0x040600 @@ -524,8 +622,7 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2, img.setNumColors(4); #endif img.save(img2); - updateColor(); - + resetUnderLines(); m_scene->addItem(m_safeRect); m_scene->addItem(m_color); if (m_view.background_list->currentIndex() > 0) m_scene->addItem(m_background); @@ -535,7 +632,21 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2, void DvdWizardMenu::createBackgroundImage(const QString &overlayMenu, const QString &img1) { - QImage img; + m_scene->clearSelection(); + if (m_safeRect->scene() != 0) m_scene->removeItem(m_safeRect); + QImage img(m_width, m_height, QImage::Format_ARGB32); + updateColor(m_view.text_color->color()); + QPainter p(&img); + p.setRenderHints(QPainter::Antialiasing, true); + p.setRenderHints(QPainter::TextAntialiasing, true); + m_scene->render(&p, QRectF(0, 0, img.width(), img.height())); + p.end(); + img.save(img1); + m_scene->addItem(m_safeRect); + return; + + + /*QImage img; if (m_view.background_list->currentIndex() == 0) { // color background if (m_isPal) @@ -560,7 +671,7 @@ void DvdWizardMenu::createBackgroundImage(const QString &overlayMenu, const QStr QRectF src(0, 0, menu.width(), menu.height()); p.drawImage(target, menu, src); p.end(); - img.save(img1); + img.save(img1);*/ } bool DvdWizardMenu::createMenu() const @@ -588,16 +699,18 @@ QMap DvdWizardMenu::buttonsInfo() { QMap info; QList list = m_scene->items(); + double ratio = (double) m_finalSize.width() / m_width; for (int i = 0; i < list.count(); i++) { if (list.at(i)->type() == QGraphicsItem::UserType + 1) { DvdButton *button = static_cast < DvdButton* >(list.at(i)); - QRect r = list.at(i)->sceneBoundingRect().toRect(); - // Make sure y1 is not odd (requested by spumux) - if (r.height() % 2 == 1) r.setHeight(r.height() + 1); - if (r.y() % 2 == 1) r.setY(r.y() - 1); + QRectF r = button->sceneBoundingRect(); + QRect adjustedRect(r.x() * ratio, r.y(), r.width() * ratio, r.height()); + // Make sure y1 is not odd (requested by spumux) + if (adjustedRect.height() % 2 == 1) adjustedRect.setHeight(adjustedRect.height() + 1); + if (adjustedRect.y() % 2 == 1) adjustedRect.setY(adjustedRect.y() - 1); QString command = button->command(); if (button->backMenu()) command.prepend("g1 = 999;"); - info.insertMulti(command, r); + info.insertMulti(command, adjustedRect); } } return info; @@ -627,6 +740,7 @@ QDomElement DvdWizardMenu::toXml() const xml.setAttribute("text_color", m_view.text_color->color().name()); xml.setAttribute("selected_color", m_view.selected_color->color().name()); xml.setAttribute("highlighted_color", m_view.highlighted_color->color().name()); + xml.setAttribute("text_shadow", (int) m_view.use_shadow->isChecked()); QList list = m_scene->items(); int buttonCount = 0; @@ -673,6 +787,8 @@ void DvdWizardMenu::loadXml(QDomElement xml) m_view.selected_color->setColor(xml.attribute("selected_color")); m_view.highlighted_color->setColor(xml.attribute("highlighted_color")); + m_view.use_shadow->setChecked(xml.attribute("text_shadow").toInt()); + QDomNodeList buttons = xml.elementsByTagName("button"); kDebug() << "// LOADING MENU 2" << buttons.count(); @@ -694,7 +810,16 @@ void DvdWizardMenu::loadXml(QDomElement xml) DvdButton *button = new DvdButton(e.attribute("text")); QFont font(e.attribute("font_family")); font.setPixelSize(e.attribute("font_size").toInt()); - font.setStyleStrategy(QFont::NoAntialias); +#if KDE_IS_VERSION(4,6,0) + if (m_view.use_shadow->isChecked()) { + QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); + shadow->setBlurRadius(7); + shadow->setOffset(4, 4); + button->setGraphicsEffect(shadow); + } +#endif + + //font.setStyleStrategy(QFont::NoAntialias); button->setFont(font); button->setTarget(e.attribute("target").toInt(), e.attribute("command")); button->setBackMenu(e.attribute("backtomenu").toInt()); diff --git a/src/dvdwizardmenu.h b/src/dvdwizardmenu.h index bde32110..e8d6f07d 100644 --- a/src/dvdwizardmenu.h +++ b/src/dvdwizardmenu.h @@ -144,6 +144,8 @@ public: void changeProfile(bool isPal); QDomElement toXml() const; void loadXml(QDomElement xml); + void prepareUnderLines(); + void resetUnderLines(); private: Ui::DvdWizardMenu_UI m_view; @@ -154,6 +156,7 @@ private: QGraphicsRectItem *m_safeRect; int m_width; int m_height; + QSize m_finalSize; #if KDE_IS_VERSION(4,7,0) KMessageWidget *m_menuMessage; #endif @@ -171,9 +174,11 @@ private slots: void deleteButton(); void updateColor(); void updateColor(QColor c); + void updateUnderlineColor(QColor c); void setBackToMenu(bool backToMenu); void slotZoom(); void slotUnZoom(); + void slotEnableShadows(int enable); }; #endif diff --git a/src/effectstack/collapsibleeffect.cpp b/src/effectstack/collapsibleeffect.cpp index 7ca82375..70733f31 100644 --- a/src/effectstack/collapsibleeffect.cpp +++ b/src/effectstack/collapsibleeffect.cpp @@ -455,7 +455,7 @@ void CollapsibleEffect::setupWidget(ItemInfo info, EffectMetaInfo *metaInfo) } connect (m_paramWidget, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int))); - connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList)), this, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList))); + connect(m_paramWidget, SIGNAL(startFilterJob(QString,QString,QString,QString,const QMap )), this, SIGNAL(startFilterJob(QString,QString,QString,QString,const QMap ))); connect (this, SIGNAL(syncEffectsPos(int)), m_paramWidget, SIGNAL(syncEffectsPos(int))); connect (m_paramWidget, SIGNAL(checkMonitorPosition(int)), this, SIGNAL(checkMonitorPosition(int))); diff --git a/src/effectstack/collapsibleeffect.h b/src/effectstack/collapsibleeffect.h index 54daa70b..0d053546 100644 --- a/src/effectstack/collapsibleeffect.h +++ b/src/effectstack/collapsibleeffect.h @@ -129,7 +129,7 @@ signals: void checkMonitorPosition(int); void seekTimeline(int); /** @brief Start an MLT filter job on this clip. */ - void startFilterJob(QString filterName, QString filterParams, QString finalFilterName, QString consumer, QString consumerParams, QStringList extraParams); + void startFilterJob(QString filterName, QString filterParams, QString consumer, QString consumerParams, const QMap extraParams); /** @brief An effect was reset, trigger param reload. */ void resetEffect(int ix); /** @brief Ask for creation of a group. */ diff --git a/src/effectstack/effectstackview2.cpp b/src/effectstack/effectstackview2.cpp index 7366b753..69c28d75 100644 --- a/src/effectstack/effectstackview2.cpp +++ b/src/effectstack/effectstackview2.cpp @@ -271,7 +271,7 @@ void EffectStackView2::connectEffect(CollapsibleEffect *currentEffect) // Check drag & drop currentEffect->installEventFilter( this ); connect(currentEffect, SIGNAL(parameterChanged(const QDomElement, const QDomElement, int)), this , SLOT(slotUpdateEffectParams(const QDomElement, const QDomElement, int))); - connect(currentEffect, SIGNAL(startFilterJob(QString,QString,QString,QString,QString,QStringList)), this , SLOT(slotStartFilterJob(QString,QString,QString,QString,QString,QStringList))); + connect(currentEffect, SIGNAL(startFilterJob(QString,QString,QString,QString,const QMap )), this , SLOT(slotStartFilterJob(QString,QString,QString,QString,const QMap ))); connect(currentEffect, SIGNAL(deleteEffect(const QDomElement)), this , SLOT(slotDeleteEffect(const QDomElement))); connect(currentEffect, SIGNAL(reloadEffects()), this , SIGNAL(reloadEffects())); connect(currentEffect, SIGNAL(resetEffect(int)), this , SLOT(slotResetEffect(int))); @@ -644,10 +644,10 @@ void EffectStackView2::slotMoveEffectUp(QList indexes, bool up) else emit changeEffectPosition(m_clipref, -1, indexes, endPos); } -void EffectStackView2::slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QStringList &extraParams) +void EffectStackView2::slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&consumer, const QString&consumerParams, const QMap &extraParams) { if (!m_clipref) return; - emit startFilterJob(m_clipref->info(), m_clipref->clipProducer(), filterName, filterParams, finalFilterName, consumer, consumerParams, extraParams); + emit startFilterJob(m_clipref->info(), m_clipref->clipProducer(), filterName, filterParams, consumer, consumerParams, extraParams); } void EffectStackView2::slotResetEffect(int ix) diff --git a/src/effectstack/effectstackview2.h b/src/effectstack/effectstackview2.h index 6c878505..dd34fe09 100644 --- a/src/effectstack/effectstackview2.h +++ b/src/effectstack/effectstackview2.h @@ -167,7 +167,7 @@ private slots: void slotSetCurrentEffect(int ix); /** @brief Triggers a filter job on this clip. */ - void slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QStringList &extraParams); + void slotStartFilterJob(const QString&filterName, const QString&filterParams, const QString&consumer, const QString&consumerParams, const QMap &extraParams); /** @brief Reset an effect to its default values. */ void slotResetEffect(int ix); @@ -223,7 +223,7 @@ signals: void updateClipRegion(ClipItem*, int, QString); void displayMessage(const QString&, int); void showComments(bool show); - void startFilterJob(ItemInfo info, const QString &clipId, const QString &filterName, const QString &filterParams, const QString&finalFilterName, const QString &consumer, const QString &consumerParams, const QStringList &extraParams); + void startFilterJob(ItemInfo info, const QString &clipId, const QString &filterName, const QString &filterParams, const QString &consumer, const QString &consumerParams, const QMap &extraParams); void addEffect(ClipItem*,QDomElement); void importClipKeyframes(GRAPHICSRECTITEM = AVWIDGET); }; diff --git a/src/effectstack/parametercontainer.cpp b/src/effectstack/parametercontainer.cpp index bcaeec55..b3820c6f 100644 --- a/src/effectstack/parametercontainer.cpp +++ b/src/effectstack/parametercontainer.cpp @@ -820,8 +820,13 @@ void ParameterContainer::slotStartFilterJobAction() paramData.append(parameters.at(j).name()+"="+parameters.at(j).value()+" "); filterparams.replace("%params", paramData); } - QStringList extra = pa.attribute("extraparams").split(' ', QString::SkipEmptyParts); - emit startFilterJob(pa.attribute("filtertag"), filterparams, pa.attribute("finalfilter"), pa.attribute("consumer"), pa.attribute("consumerparams"), extra); + QMap extraParams; + QDomNodeList jobparams = pa.elementsByTagName("jobparam"); + for (int j = 0; j < jobparams.count(); j++) { + QDomElement e = jobparams.item(j).toElement(); + extraParams.insert(e.attribute("name"), e.text().toUtf8()); + } + emit startFilterJob(pa.attribute("filtertag"), filterparams, pa.attribute("consumer"), pa.attribute("consumerparams"), extraParams); kDebug()<<" - - -PROPS:\n"<extra); /** @brief Request import of keyframes from clip data. */ void importClipKeyframes(); }; diff --git a/src/kthumb.cpp b/src/kthumb.cpp index 350f14f4..86dcab93 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -66,7 +66,7 @@ void KThumb::setProducer(Mlt::Producer *producer) if (m_producer) m_clipManager->stopThumbs(m_id); m_intraFramesQueue.clear(); m_intra.waitForFinished(); - m_mutex.lock(); + QMutexLocker lock(&m_mutex); m_producer = producer; // FIXME: the profile() call leaks an object, but trying to free // it leads to a double-free in Profile::~Profile() @@ -75,7 +75,6 @@ void KThumb::setProducer(Mlt::Producer *producer) m_dar = profile->dar(); m_ratio = (double) profile->width() / profile->height(); } - m_mutex.unlock(); } void KThumb::clearProducer() @@ -118,11 +117,18 @@ void KThumb::getThumb(int frame) const int theight = KdenliveSettings::trackheight(); const int swidth = (int)(theight * m_ratio + 0.5); const int dwidth = (int)(theight * m_dar + 0.5); - QImage img = getProducerFrame(frame, swidth, dwidth, theight); emit thumbReady(frame, img); } +void KThumb::getGenericThumb(int frame, int height, int type) +{ + const int swidth = (int)(height * m_ratio + 0.5); + const int dwidth = (int)(height * m_dar + 0.5); + QImage img = getProducerFrame(frame, swidth, dwidth, height); + m_clipManager->projectTreeThumbReady(m_id, frame, img, type); +} + QImage KThumb::extractImage(int frame, int width, int height) { if (m_producer == NULL) { @@ -139,9 +145,6 @@ QPixmap KThumb::getImage(KUrl url, int frame, int width, int height) Mlt::Profile profile(KdenliveSettings::current_profile().toUtf8().constData()); QPixmap pix(width, height); if (url.isEmpty()) return pix; - - //""); - //Mlt::Producer producer(profile, "xml-string", tmp); Mlt::Producer *producer = new Mlt::Producer(profile, url.path().toUtf8().constData()); double swidth = (double) profile.width() / profile.height(); pix = QPixmap::fromImage(getFrame(producer, frame, (int) (height * swidth + 0.5), width, height)); @@ -162,12 +165,14 @@ QImage KThumb::getProducerFrame(int framepos, int frameWidth, int displayWidth, p.fill(QColor(Qt::black).rgb()); return p; } - m_mutex.lock(); + QMutexLocker lock(&m_mutex); m_producer->seek(framepos); Mlt::Frame *frame = m_producer->get_frame(); + frame->set("rescale.interp", "nearest"); + frame->set("deinterlace_method", "onefield"); + frame->set("top_field_first", -1 ); QImage p = getFrame(frame, frameWidth, displayWidth, height); delete frame; - m_mutex.unlock(); return p; } @@ -187,6 +192,9 @@ QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int frameWidth, i producer->seek(framepos); Mlt::Frame *frame = producer->get_frame(); + frame->set("rescale.interp", "nearest"); + frame->set("deinterlace_method", "onefield"); + frame->set("top_field_first", -1 ); QImage p = getFrame(frame, frameWidth, displayWidth, height); delete frame; return p; @@ -201,17 +209,14 @@ QImage KThumb::getFrame(Mlt::Frame *frame, int frameWidth, int displayWidth, int p.fill(QColor(Qt::red).rgb()); return p; } - + int ow = frameWidth; int oh = height; mlt_image_format format = mlt_image_rgb24a; - frame->set("rescale.interp", "nearest"); - frame->set("deinterlace_method", "onefield"); - frame->set("top_field_first", -1 ); //frame->set("progressive", "1"); if (ow % 2 == 1) ow++; - const uchar* imagedata = frame->get_image(format, ow, oh); QImage image(ow, oh, QImage::Format_ARGB32_Premultiplied); + const uchar* imagedata = frame->get_image(format, ow, oh); memcpy(image.bits(), imagedata, ow * oh * 4);//.byteCount()); //const uchar* imagedata = frame->get_image(format, ow, oh); diff --git a/src/kthumb.h b/src/kthumb.h index 142bff41..65e1cb8b 100644 --- a/src/kthumb.h +++ b/src/kthumb.h @@ -71,6 +71,7 @@ Q_OBJECT public: QImage findCachedThumb(const QString &path); #endif void getThumb(int frame); + void getGenericThumb(int frame, int height, int type); public slots: void updateClipUrl(KUrl url, const QString &hash); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4a10ec80..9eadf01b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -280,7 +280,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & m_effectStack = new EffectStackView2(m_projectMonitor); m_effectStackDock->setWidget(m_effectStack); addDockWidget(Qt::TopDockWidgetArea, m_effectStackDock); - connect(m_effectStack, SIGNAL(startFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QStringList&)), m_projectList, SLOT(slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QStringList&))); + connect(m_effectStack, SIGNAL(startFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QMap &)), m_projectList, SLOT(slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QMap &))); m_transitionConfigDock = new QDockWidget(i18n("Transition"), this); m_transitionConfigDock->setObjectName("transition"); @@ -1967,6 +1967,7 @@ bool MainWindow::closeCurrentDocument(bool saveChanges) break; } } + slotTimelineClipSelected(NULL, false); m_clipMonitor->slotSetClipProducer(NULL); m_projectList->slotResetProjectList(); m_timelineArea->removeTab(m_timelineArea->indexOf(w)); @@ -2528,7 +2529,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha disconnect(m_activeTimeline->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay())); disconnect(m_activeTimeline->projectView(), SIGNAL(displayMessage(const QString&, MessageType)), m_messageLabel, SLOT(setMessage(const QString&, MessageType))); disconnect(m_activeTimeline->projectView(), SIGNAL(showClipFrame(DocClipBase *, QPoint, bool, const int)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool, const int))); - disconnect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap,QStringList)), m_activeTimeline->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap,QStringList))); + disconnect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, stringMap,stringMap)), m_activeTimeline->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, stringMap, stringMap))); disconnect(m_activeTimeline, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(slotActivateMonitor())); disconnect(m_activeTimeline, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int))); @@ -2610,7 +2611,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(Transition*))); - connect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap,QStringList)), trackView->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap,QStringList))); + connect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, stringMap,stringMap)), trackView->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, stringMap,stringMap))); connect(m_projectList, SIGNAL(addMarkers(const QString &, QList )), trackView->projectView(), SLOT(slotAddClipMarker(const QString &, QList ))); @@ -3328,6 +3329,13 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip) // any type of clip but a title ClipProperties *dia = new ClipProperties(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this); + + if (clip->clipType() == AV || clip->clipType() == VIDEO || clip->clipType() == PLAYLIST) { + // request clip thumbnails + m_activeDocument->clipManager()->requestThumbs(QString('?' + clip->getId()), QList() << clip->getClipThumbFrame()); + connect(m_activeDocument->clipManager(), SIGNAL(gotClipPropertyThumbnail(const QString&,QImage)), dia, SLOT(slotGotThumbnail(const QString&,QImage))); + } + connect(dia, SIGNAL(addMarkers(const QString &, QList )), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, QList ))); connect(dia, SIGNAL(deleteAnalysis(QString,QString)), m_activeTimeline->projectView(), SLOT(slotAddClipExtraData(QString,QString))); connect(m_activeTimeline->projectView(), SIGNAL(updateClipMarkers(DocClipBase *)), dia, SLOT(slotFillMarkersList(DocClipBase *))); diff --git a/src/monitor.cpp b/src/monitor.cpp index d7491dea..67b35e92 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -830,6 +830,7 @@ void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpda { if (render == NULL) return; if (clip == NULL && m_currentClip != NULL) { + m_currentClip->lastSeekPosition = render->seekFramePosition(); kDebug()<<"// SETTING NULL CLIP MONITOR"; m_currentClip = NULL; m_length = -1; @@ -838,7 +839,9 @@ void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpda } if (clip != m_currentClip || forceUpdate) { + if (m_currentClip) m_currentClip->lastSeekPosition = render->seekFramePosition(); m_currentClip = clip; + if (position == -1) position = clip->lastSeekPosition; if (m_currentClip) slotActivateMonitor(); updateMarkers(clip); Mlt::Producer *prod = NULL; diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 8bc65c36..022b1971 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -1360,7 +1360,7 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties) QList cuts = clip->cutZones(); if (!cuts.isEmpty()) { for (int i = 0; i < cuts.count(); i++) { - SubProjectItem *sub = new SubProjectItem(item, cuts.at(i).zone.x(), cuts.at(i).zone.y(), cuts.at(i).description); + SubProjectItem *sub = new SubProjectItem(m_render->dar(), item, cuts.at(i).zone.x(), cuts.at(i).zone.y(), cuts.at(i).description); if (!clip->getClipHash().isEmpty()) { QString cachedPixmap = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "thumbs/" + clip->getClipHash() + '#' + QString::number(cuts.at(i).zone.x()) + ".png"; if (QFile::exists(cachedPixmap)) { @@ -2001,6 +2001,23 @@ void ProjectList::setDocument(KdenliveDoc *doc) connect(m_doc->clipManager(), SIGNAL(missingClip(const QString &)), this, SLOT(slotMissingClip(const QString &))); connect(m_doc->clipManager(), SIGNAL(availableClip(const QString &)), this, SLOT(slotAvailableClip(const QString &))); connect(m_doc->clipManager(), SIGNAL(checkAllClips(bool, bool, QStringList)), this, SLOT(updateAllClips(bool, bool, QStringList))); + connect(m_doc->clipManager(), SIGNAL(thumbReady(const QString &, int, QImage)), this, SLOT(slotSetThumbnail(const QString &, int, QImage))); +} + +void ProjectList::slotSetThumbnail(const QString &id, int framePos, QImage img) +{ + QString fullid = id + '#' + QString::number(framePos); + ProjectItem *pItem = NULL; + QTreeWidgetItem *item = getAnyItemById(fullid); + if (item && item->parent()) pItem = static_cast (item->parent()); + if (!item && framePos == 0) pItem = getItemById(id); + if (!item && !pItem) return; + if (item) item->setData(0, Qt::DecorationRole, QPixmap::fromImage(img)); + else if (pItem) pItem->setData(0, Qt::DecorationRole, QPixmap::fromImage(img)); + if (pItem) { + QString hash = pItem->getClipHash(); + if (!hash.isEmpty()) m_doc->cacheImage(hash + '#' + QString::number(framePos), img); + } } QList ProjectList::documentClipList() const @@ -2576,17 +2593,14 @@ void ProjectList::addClipCut(const QString &id, int in, int out, const QString d DocClipBase *base = clip->referencedClip(); base->addCutZone(in, out); monitorItemEditing(false); - SubProjectItem *sub = new SubProjectItem(clip, in, out, desc); + SubProjectItem *sub = new SubProjectItem(m_render->dar(), clip, in, out, desc); if (newItem && desc.isEmpty() && !m_listView->isColumnHidden(1)) { if (!clip->isExpanded()) clip->setExpanded(true); m_listView->scrollToItem(sub); m_listView->editItem(sub, 1); } - QImage img = clip->referencedClip()->extractImage(in, (int)(sub->sizeHint(0).height() * m_render->dar()), sub->sizeHint(0).height() - 2); - sub->setData(0, Qt::DecorationRole, QPixmap::fromImage(img)); - QString hash = clip->getClipHash(); - if (!hash.isEmpty()) m_doc->cacheImage(hash + '#' + QString::number(in), img); + m_doc->clipManager()->requestThumbs(QString('#' + id), QList () << in); monitorItemEditing(true); } emit projectModified(); @@ -2995,9 +3009,9 @@ void ProjectList::slotProcessJobs() MeltJob *jb = static_cast (job); jb->setProducer(currentClip->getProducer(), currentClip->fileURL()); if (jb->isProjectFilter()) - connect(job, SIGNAL(gotFilterJobResults(QString,int, int, QString,stringMap,QStringList)), this, SLOT(slotGotFilterJobResults(QString,int, int, QString,stringMap,QStringList))); + connect(job, SIGNAL(gotFilterJobResults(QString,int, int, stringMap,stringMap)), this, SLOT(slotGotFilterJobResults(QString,int, int,stringMap,stringMap))); else - connect(job, SIGNAL(gotFilterJobResults(QString,int, int, QString,stringMap,QStringList)), this, SIGNAL(gotFilterJobResults(QString,int, int, QString,stringMap,QStringList))); + connect(job, SIGNAL(gotFilterJobResults(QString,int, int, stringMap,stringMap)), this, SIGNAL(gotFilterJobResults(QString,int, int,stringMap,stringMap))); } job->startJob(); if (job->jobStatus == JOBDONE) { @@ -3422,19 +3436,19 @@ void ProjectList::discardJobs(const QString &id, JOBTYPE type) { } } -void ProjectList::slotStartFilterJob(ItemInfo info, const QString&id, const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QStringList &extraParams) +void ProjectList::slotStartFilterJob(ItemInfo info, const QString&id, const QString&filterName, const QString&filterParams, const QString&consumer, const QString&consumerParams, const QMap &extraParams) { ProjectItem *item = getItemById(id); if (!item) return; QStringList jobParams; jobParams << QString::number(info.cropStart.frames(m_fps)) << QString::number((info.cropStart + info.cropDuration).frames(m_fps)); - jobParams << QString() << filterName << filterParams << consumer << consumerParams << QString::number(info.startPos.frames(m_fps)) << QString::number(info.track) << finalFilterName; + jobParams << QString() << filterName << filterParams << consumer << consumerParams << QString::number(info.startPos.frames(m_fps)) << QString::number(info.track); MeltJob *job = new MeltJob(item->clipType(), id, jobParams, extraParams); if (job->isExclusive() && hasPendingJob(item, job->jobType)) { delete job; return; } - job->description = i18n("Filter %1", finalFilterName); + job->description = i18n("Filter %1", extraParams.value("finalfilter")); m_jobList.append(job); setJobStatus(item, job->jobType, JOBWAITING, 0, job->statusMessage()); slotCheckJobProcess(); @@ -3478,16 +3492,16 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c jobParams << filterName << "bounding=\"25%x25%:25%x25\" shot_change_list=0"; // Consumer jobParams << "null" << "all=1 terminate_on_pause=1 real_time=-1"; - QStringList extraParams; - extraParams << "key:shot_change_list"; - extraParams << "projecttreefilter"; + QMap extraParams; + extraParams.insert("key", "shot_change_list"); + extraParams.insert("projecttreefilter", "1"); if (ui.add_markers->isChecked()) { // We want to create markers - extraParams << QString("addmarkers:%1").arg(ui.marker_type->currentIndex()); + extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex())); } if (ui.cut_scenes->isChecked()) { // We want to cut scenes - extraParams << "cutscenes"; + extraParams.insert("cutscenes", "1"); } delete d; processClipJob(ids, QString(), false, jobParams, i18n("Auto split"), extraParams); @@ -3495,15 +3509,15 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c else { QPointer d = new ClipStabilize(destination, ids.count(), filterName); if (d->exec() == QDialog::Accepted) { - QStringList extraParams; - extraParams << "producer_profile"; + QMap extraParams; + extraParams.insert("producer_profile", "1"); processClipJob(ids, d->destination(), d->autoAddClip(), d->params(), d->desc(), extraParams); } delete d; } } -void ProjectList::processClipJob(QStringList ids, const QString&destination, bool autoAdd, QStringList jobParams, const QString &description, QStringList extraParams) +void ProjectList::processClipJob(QStringList ids, const QString&destination, bool autoAdd, QStringList jobParams, const QString &description, QMap extraParams) { QStringList preParams; // in and out @@ -3597,38 +3611,31 @@ void ProjectList::slotClosePopup() m_errorLog.clear(); } -void ProjectList::slotGotFilterJobResults(QString id, int , int , QString filter, stringMap results, QStringList extra) +void ProjectList::slotGotFilterJobResults(QString id, int , int , stringMap results, stringMap filterInfo) { + // Currently, only the first value of results is used + kDebug()<<"// FILTER RES:\n"<setText(i18n("Auto Split Clip")); - foreach (QString pos, returnData) { + foreach (QString pos, value) { if (!pos.contains("=")) continue; int newPos = pos.section("=", 0, 0).toInt(); // Don't use scenes shorter than 1 second @@ -3648,7 +3655,7 @@ void ProjectList::slotGotFilterJobResults(QString id, int , int , QString filter command->setText(i18n("Add Markers")); QList markersList; int index = 1; - foreach (QString pos, returnData) { + foreach (QString pos, value) { if (!pos.contains("=")) continue; int newPos = pos.section("=", 0, 0).toInt(); // Don't use scenes shorter than 1 second @@ -3660,12 +3667,12 @@ void ProjectList::slotGotFilterJobResults(QString id, int , int , QString filter } emit addMarkers(id, markersList); } - if (!dataProcessed || extra.contains("storedata")) { + if (!dataProcessed || filterInfo.contains("storedata")) { // Store returned data as clip extra data - - clip->referencedClip()->setAnalysisData(i18n("Motion vectors"), results.value(returnKey)); + clip->referencedClip()->setAnalysisData(filterInfo.contains("displaydataname") ? filterInfo.value("displaydataname") : key, results.value(key)); emit updateAnalysisData(clip->referencedClip()); } } + #include "projectlist.moc" diff --git a/src/projectlist.h b/src/projectlist.h index 7019595c..ef290dad 100644 --- a/src/projectlist.h +++ b/src/projectlist.h @@ -330,7 +330,8 @@ public slots: /** @brief Start transcoding selected clips. */ void slotTranscodeClipJob(const QString &condition, QString params, QString desc); /** @brief Start an MLT process job. */ - void slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QString&,const QStringList&); + void slotStartFilterJob(ItemInfo, const QString&,const QString&,const QString&,const QString&,const QString&,const QMap &); + void slotSetThumbnail(const QString &id, int framePos, QImage img); private: @@ -424,7 +425,7 @@ private: /** @brief Get the list of job names for current clip. */ QStringList getPendingJobs(const QString &id); /** @brief Start an MLT process job. */ - void processClipJob(QStringList ids, const QString&destination, bool autoAdd, QStringList jobParams, const QString &description, QStringList extraParams = QStringList()); + void processClipJob(QStringList ids, const QString&destination, bool autoAdd, QStringList jobParams, const QString &description, QMap extraParams = QMap ()); private slots: void slotClipSelected(); @@ -491,7 +492,7 @@ private slots: /** @brief close warning info passive popup. */ void slotClosePopup(); /** @brief process clip job result. */ - void slotGotFilterJobResults(QString ,int , int, QString, stringMap, QStringList); + void slotGotFilterJobResults(QString ,int , int, stringMap, stringMap); signals: void clipSelected(DocClipBase *, QPoint zone = QPoint(), bool forceUpdate = false); @@ -524,7 +525,7 @@ signals: void gotProxy(const QString); void checkJobProcess(); /** @brief A Filter Job produced results, send them back to the clip. */ - void gotFilterJobResults(const QString &id, int startPos, int track, const QString &filterName, stringMap params, QStringList extre); + void gotFilterJobResults(const QString &id, int startPos, int track, stringMap params, stringMap extra); void pauseMonitor(); void updateAnalysisData(DocClipBase *); void addMarkers(const QString &, QList ); diff --git a/src/projecttree/meltjob.cpp b/src/projecttree/meltjob.cpp index ed170fdb..55926077 100644 --- a/src/projecttree/meltjob.cpp +++ b/src/projecttree/meltjob.cpp @@ -35,7 +35,7 @@ static void consumer_frame_render(mlt_consumer, MeltJob * self, mlt_frame /*fram self->emitFrameNumber(); } -MeltJob::MeltJob(CLIPTYPE cType, const QString &id, QStringList parameters, QStringList extraParams) : AbstractClipJob(MLTJOB, cType, id, parameters), +MeltJob::MeltJob(CLIPTYPE cType, const QString &id, QStringList parameters, QMap extraParams) : AbstractClipJob(MLTJOB, cType, id, parameters), addClipToProject(0), m_producer(NULL), m_profile(NULL), @@ -80,19 +80,7 @@ void MeltJob::startJob() if (!m_params.isEmpty()) startPos = m_params.takeFirst().toInt(); int track = -1; if (!m_params.isEmpty()) track = m_params.takeFirst().toInt(); - QString finalFilter; - if (!m_params.isEmpty()) finalFilter = m_params.takeFirst(); - else finalFilter = filter; - - // Check if we want to return analysis data - QString properties; - for (int i = 0; i < m_extra.count(); i++) { - if (m_extra.at(i).startsWith("key:")) { - properties = m_extra.at(i).section(':', 1); - break; - } - } - + if (!m_extra.contains("finalfilter")) m_extra.insert("finalfilter", filter); if (out != -1 && out <= in) { m_errorMessage.append(i18n("Clip zone undefined (%1 - %2).", in, out)); @@ -115,7 +103,7 @@ void MeltJob::startJob() prod = tmp->cut(in, out); delete tmp; } - if (m_extra.contains("prducer_profile")) { + if (m_extra.contains("producer_profile")) { m_profile->from_producer(*prod); m_profile->set_explicit(true); } @@ -174,13 +162,10 @@ void MeltJob::startJob() } m_consumer->stop(); - QStringList wanted = properties.split(',', QString::SkipEmptyParts); - stringMap jobResults; - foreach(const QString &key, wanted) { - QString value = mltFilter.get(key.toUtf8().constData()); - jobResults.insert(key, value); - } - if (!jobResults.isEmpty() && jobStatus != JOBABORTED) emit gotFilterJobResults(m_clipId, startPos, track, finalFilter, jobResults, m_extra); + QMap jobResults; + if (m_extra.contains("key")) + jobResults.insert(m_extra.value("key"), mltFilter.get(m_extra.value("key").toUtf8().constData())); + if (!jobResults.isEmpty() && jobStatus != JOBABORTED) emit gotFilterJobResults(m_clipId, startPos, track, jobResults, m_extra); setStatus(JOBDONE); delete m_consumer; delete prod; diff --git a/src/projecttree/meltjob.h b/src/projecttree/meltjob.h index d3736503..41671a6b 100644 --- a/src/projecttree/meltjob.h +++ b/src/projecttree/meltjob.h @@ -41,7 +41,7 @@ class MeltJob : public AbstractClipJob Q_OBJECT public: - MeltJob(CLIPTYPE cType, const QString &id, QStringList parameters, QStringList extraParams = QStringList()); + MeltJob(CLIPTYPE cType, const QString &id, QStringList parameters, QMap extraParams = QMap ()); virtual ~ MeltJob(); const QString destination() const; void startJob(); @@ -62,10 +62,10 @@ private: QString m_dest; QString m_url; int m_length; - QStringList m_extra; + QMap m_extra; signals: - void gotFilterJobResults(const QString &id, int startPos, int track, const QString &filterName, stringMap params, QStringList extraParam); + void gotFilterJobResults(const QString &id, int startPos, int track, stringMap result, stringMap extra); }; #endif diff --git a/src/renderwidget.cpp b/src/renderwidget.cpp index 35e40814..89887ea1 100644 --- a/src/renderwidget.cpp +++ b/src/renderwidget.cpp @@ -980,6 +980,7 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const render_process_args << "consumer:" + (scriptExport ? "$SOURCE" : playlistPath); else render_process_args << (scriptExport ? "$SOURCE" : playlistPath); + render_process_args << (scriptExport ? "$TARGET" : KUrl(dest).url()); render_process_args << paramsList; diff --git a/src/smallruler.cpp b/src/smallruler.cpp index 0cf185b0..24a016dd 100644 --- a/src/smallruler.cpp +++ b/src/smallruler.cpp @@ -39,6 +39,7 @@ SmallRuler::SmallRuler(MonitorManager *manager, Render *render, QWidget *parent) ,m_manager(manager) ,m_render(render) ,m_lastSeekPosition(SEEK_INACTIVE) + ,m_cursorColor(palette().text()) { m_zoneStart = 10; m_zoneEnd = 60; @@ -135,10 +136,20 @@ void SmallRuler::mousePressEvent(QMouseEvent * event) } } +// virtual +void SmallRuler::leaveEvent(QEvent * event) +{ + QWidget::leaveEvent(event); + if (m_cursorColor == palette().highlight()) { + m_cursorColor = palette().text(); + update(); + } +} // virtual void SmallRuler::mouseMoveEvent(QMouseEvent * event) { + QWidget::mouseMoveEvent(event); const int pos = event->x() / m_scale; if (event->buttons() & Qt::LeftButton) { m_render->seekToFrame(pos); @@ -146,6 +157,15 @@ void SmallRuler::mouseMoveEvent(QMouseEvent * event) update(); } else { + if (m_cursorColor == palette().text() && qAbs(pos - m_cursorFramePosition) * m_scale < 7) { + // Mouse is over cursor + m_cursorColor = palette().highlight(); + update(); + } + else if (m_cursorColor == palette().highlight() && qAbs(pos - m_cursorFramePosition) * m_scale >= 7) { + m_cursorColor = palette().text(); + update(); + } if (qAbs((pos - m_zoneStart) * m_scale) < 4) { setToolTip(i18n("Zone start: %1", m_manager->timecode().getTimecodeFromFrames(m_zoneStart))); } else if (qAbs((pos - m_zoneEnd) * m_scale) < 4) { @@ -236,7 +256,7 @@ void SmallRuler::paintEvent(QPaintEvent *e) // draw pointer QPolygon pa(3); pa.setPoints(3, cursorPos - 6, 10, cursorPos + 6, 10, cursorPos/*+0*/, 4); - p.setBrush(palette().text()); + p.setBrush(m_cursorColor); p.setPen(Qt::NoPen); p.drawPolygon(pa); diff --git a/src/smallruler.h b/src/smallruler.h index 6080ca2e..5e0a5736 100644 --- a/src/smallruler.h +++ b/src/smallruler.h @@ -47,6 +47,7 @@ public: protected: virtual void paintEvent(QPaintEvent *e); virtual void resizeEvent(QResizeEvent *); + virtual void leaveEvent(QEvent * event); private: int m_cursorPosition; @@ -63,6 +64,7 @@ private: MonitorManager *m_manager; Render *m_render; int m_lastSeekPosition; + QBrush m_cursorColor; void updatePixmap(); public slots: diff --git a/src/subprojectitem.cpp b/src/subprojectitem.cpp index 9c8ad1ef..eba677b1 100644 --- a/src/subprojectitem.cpp +++ b/src/subprojectitem.cpp @@ -24,22 +24,27 @@ #include "kdenlivesettings.h" #include "docclipbase.h" + #include #include #include const int DurationRole = Qt::UserRole + 1; +const int itemHeight = 30; -SubProjectItem::SubProjectItem(QTreeWidgetItem * parent, int in, int out, QString description) : +SubProjectItem::SubProjectItem(double display_ratio, QTreeWidgetItem * parent, int in, int out, QString description) : QTreeWidgetItem(parent, PROJECTSUBCLIPTYPE), m_in(in), m_out(out), m_description(description) { - setSizeHint(0, QSize(65, 30)); + setSizeHint(0, QSize((int) (itemHeight * display_ratio) + 2, itemHeight + 2)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled); QString name = Timecode::getStringTimecode(in, KdenliveSettings::project_fps()); setText(0, name); setText(1, description); GenTime duration = GenTime(out - in, KdenliveSettings::project_fps()); if (duration != GenTime()) setData(0, DurationRole, Timecode::getEasyTimecode(duration, KdenliveSettings::project_fps())); + QPixmap pix((int) (itemHeight * display_ratio), itemHeight); + pix.fill(Qt::gray); + setData(0, Qt::DecorationRole, pix); //setFlags(Qt::NoItemFlags); //kDebug() << "Constructed with clipId: " << m_clipId; } @@ -54,6 +59,12 @@ int SubProjectItem::numReferences() const return 0; } +//static +int SubProjectItem::itemDefaultHeight() +{ + return itemHeight; +} + QDomElement SubProjectItem::toXml() const { //return m_clip->toXML(); diff --git a/src/subprojectitem.h b/src/subprojectitem.h index 9a5a01cf..d3efd85a 100644 --- a/src/subprojectitem.h +++ b/src/subprojectitem.h @@ -38,7 +38,7 @@ class DocClipBase; class SubProjectItem : public QTreeWidgetItem { public: - SubProjectItem(QTreeWidgetItem * parent, int in, int out, QString description = QString()); + SubProjectItem(double display_ratio, QTreeWidgetItem * parent, int in, int out, QString description = QString()); virtual ~SubProjectItem(); QDomElement toXml() const; int numReferences() const; @@ -47,6 +47,7 @@ public: void setZone(QPoint p); QString description() const; void setDescription(QString desc); + static int itemDefaultHeight(); /** Make sure folders appear on top of the tree widget */ virtual bool operator<(const QTreeWidgetItem &other)const { diff --git a/src/transitionsettings.cpp b/src/transitionsettings.cpp index 2f3b9eda..312cf60d 100644 --- a/src/transitionsettings.cpp +++ b/src/transitionsettings.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - effecstackedit.h - description + effecstackedit.cpp - description ------------------- begin : Mar 15 2008 copyright : (C) 2008 by Marco Gittler @@ -110,9 +110,12 @@ void TransitionSettings::slotTransitionChanged(bool reinit, bool updateCurrent) QDomElement e = m_usedTransition->toXML().cloneNode().toElement(); if (reinit) { // Reset the transition parameters to the default one + disconnect(m_effectEdit->monitor(), SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int))); QDomElement newTransition = MainWindow::transitions.getEffectByName(transitionList->currentText()).cloneNode().toElement(); slotUpdateEffectParams(e, newTransition); m_effectEdit->transferParamDesc(newTransition, m_usedTransition->info(), false); + if (m_effectEdit->needsMonitorEffectScene()) + connect(m_effectEdit->monitor(), SIGNAL(renderPosition(int)), this, SLOT(slotRenderPos(int))); } else if (!updateCurrent) { // Transition changed, update parameters dialog //slotUpdateEffectParams(e, e); diff --git a/src/widgets/clipproperties_ui.ui b/src/widgets/clipproperties_ui.ui index 95516d38..c6080d51 100644 --- a/src/widgets/clipproperties_ui.ui +++ b/src/widgets/clipproperties_ui.ui @@ -16,9 +16,6 @@ - - Image preview - Qt::AlignCenter diff --git a/src/widgets/dvdwizardmenu_ui.ui b/src/widgets/dvdwizardmenu_ui.ui index f7b3fe9b..ba524d85 100644 --- a/src/widgets/dvdwizardmenu_ui.ui +++ b/src/widgets/dvdwizardmenu_ui.ui @@ -6,8 +6,8 @@ 0 0 - 335 - 371 + 439 + 368 @@ -56,17 +56,17 @@ - + - + Target - + @@ -76,6 +76,13 @@ + + + + Back to menu + + + @@ -96,28 +103,49 @@ - + - - + + + + + + + + 255 + 255 + 255 + + + + + + - Button colors + Shadow + + + true - + - + - + Underline + + + + 255 - 255 - 255 + 85 + 0 @@ -134,25 +162,20 @@ - - - - 255 - 85 - 0 - + + + Qt::Horizontal - + + + 40 + 20 + + + - - - - Back to menu - - - @@ -270,14 +293,14 @@ - KIntSpinBox - QSpinBox -
knuminput.h
+ KColorButton + QPushButton +
kcolorbutton.h
- KUrlRequester - QFrame -
kurlrequester.h
+ KComboBox + QComboBox +
kcombobox.h
KLineEdit @@ -285,14 +308,14 @@
klineedit.h
- KComboBox - QComboBox -
kcombobox.h
+ KIntSpinBox + QSpinBox +
knuminput.h
- KColorButton - QPushButton -
kcolorbutton.h
+ KUrlRequester + QFrame +
kurlrequester.h