Commit 2e892304 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fixes and updates preparing the new qtblend transition/effect

parent 51c4bfa4
......@@ -103,6 +103,7 @@ volume
lift_gamma_gain
audiowaveform
audiowave
qtblend
#Effects not usable with a simple GUI
sox
......
......@@ -122,6 +122,7 @@ movit_saturation.xml
movit_unsharp_mask.xml
movit_vignette.xml
movit_white_balance.xml
qtblend.xml
rotoscoping.xml
speed.xml
swapchannels.xml
......
<!DOCTYPE kpartgui>
<effect tag="qtblend" id="qtblend">
<name>Transform</name>
<description>Position, scale and opacity.</description>
<author>Jean-Baptiste Mardelle</author>
<parameter type="animatedrect" name="transition.rect" default="0 0 %width %height 1">
<name>Rectangle</name>
</parameter>
<parameter type="list" name="transition.compositing" default="0" paramlist="0;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;6;8">
<paramlistdisplay>Alpha blend,Xor,Plus,Multiply,Screen,Overlay,Darken,Lighten,Color dodge,Color burn,Hard light,Soft light,Difference,Exclusion,Bitwise or,Bitwise and,Bitwise xor,Bitwise nor,Bitwise nand,Bitwise not xor,Destination in,Destination out</paramlistdisplay>
<name>Compositing</name>
</parameter>
<parameter type="bool" name="transition.distort" default="0" min="0" max="1">
<name>Distort</name>
</parameter>
</effect>
......@@ -3,7 +3,7 @@
<name>Composite and transform</name>
<description>Composites second input on the first input with user-defined blend mode, opacity and scale.</description>
<author>Jean-Baptiste Mardelle</author>
<parameter type="animatedrect" name="rect" default="0 0 %width %height">
<parameter type="animatedrect" name="rect" default="0 0 %width %height 1">
<name>Rectangle</name>
</parameter>
<parameter type="list" name="compositing" default="0" paramlist="0;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;6;8">
......
......@@ -1848,8 +1848,12 @@ bool DocumentValidator::checkMovit()
bool hasWB = ix > -1;
ix = MainWindow::videoEffects.hasEffect(QStringLiteral("frei0r.IIRblur"), QStringLiteral("frei0r.IIRblur"));
bool hasBlur = ix > -1;
ix = MainWindow::transitions.hasTransition(QStringLiteral("frei0r.cairoblend"));
bool hasCairo = ix > -1;
QString compositeTrans;
if (MainWindow::transitions.hasTransition(QStringLiteral("qtblend"))) {
compositeTrans = QStringLiteral("qtblend");
} else if (MainWindow::transitions.hasTransition(QStringLiteral("frei0r.cairoblend"))) {
compositeTrans = QStringLiteral("frei0r.cairoblend");
}
// Parse all effects in document
QDomNodeList filters = m_doc.elementsByTagName(QStringLiteral("filter"));
......@@ -1913,9 +1917,9 @@ bool DocumentValidator::checkMovit()
if (!transId.startsWith(QLatin1String("movit."))) {
continue;
}
if (transId == QLatin1String("movit.overlay") && hasCairo) {
if (transId == QLatin1String("movit.overlay") && !compositeTrans.isEmpty()) {
// Convert to frei0r.cairoblend
EffectsList::setProperty(t, QStringLiteral("mlt_service"), QStringLiteral("frei0r.cairoblend"));
EffectsList::setProperty(t, QStringLiteral("mlt_service"), compositeTrans);
convertedFilters << transId;
continue;
}
......
......@@ -41,6 +41,7 @@
#include "utils/KoIconUtils.h"
#include "mltcontroller/bincontroller.h"
#include "mltcontroller/effectscontroller.h"
#include "timeline/transitionhandler.h"
#include <KMessageBox>
#include <KRecentDirs>
......@@ -445,20 +446,20 @@ QDomDocument KdenliveDoc::createEmptyDocument(const QList <TrackInfo> &tracks)
// create playlists
int total = tracks.count();
// The lower video track will recieve composite transitions
int lowerVideoTrack = -1;
int lowestVideoTrack = -1;
for (int i = 0; i < total; ++i) {
QDomElement playlist = doc.createElement(QStringLiteral("playlist"));
playlist.setAttribute(QStringLiteral("id"), "playlist" + QString::number(i+1));
playlist.setAttribute(QStringLiteral("kdenlive:track_name"), tracks.at(i).trackName);
if (tracks.at(i).type == AudioTrack) {
playlist.setAttribute(QStringLiteral("kdenlive:audio_track"), 1);
} else if (lowerVideoTrack == -1) {
} else if (lowestVideoTrack == -1) {
// Register first video track
lowerVideoTrack = i + 1;
lowestVideoTrack = i + 1;
}
mlt.appendChild(playlist);
}
QString compositeService = TransitionHandler::compositeTransition();
QDomElement track0 = doc.createElement(QStringLiteral("track"));
track0.setAttribute(QStringLiteral("producer"), QStringLiteral("black_track"));
tractor.appendChild(track0);
......@@ -518,17 +519,17 @@ QDomDocument KdenliveDoc::createEmptyDocument(const QList <TrackInfo> &tracks)
tractor.appendChild(transition);
}
if (i >= lowerVideoTrack && tracks.at(i).type == VideoTrack) {
if (i >= lowestVideoTrack && tracks.at(i).type == VideoTrack) {
// Only add composite transition if both tracks are video
QDomElement transition = doc.createElement(QStringLiteral("transition"));
property = doc.createElement(QStringLiteral("property"));
property.setAttribute(QStringLiteral("name"), QStringLiteral("mlt_service"));
property.appendChild(doc.createTextNode(KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend"));
property.appendChild(doc.createTextNode(compositeService));
transition.appendChild(property);
property = doc.createElement(QStringLiteral("property"));
property.setAttribute(QStringLiteral("name"), QStringLiteral("a_track"));
property.appendChild(doc.createTextNode(QString::number(lowerVideoTrack)));
property.appendChild(doc.createTextNode(QString::number(lowestVideoTrack)));
transition.appendChild(property);
property = doc.createElement(QStringLiteral("property"));
......
......@@ -45,7 +45,7 @@ QDomElement EffectsList::getEffectByName(const QString & name) const
QDomNodeList params = effect.elementsByTagName(QStringLiteral("parameter"));
for (int i = 0; i < params.count(); ++i) {
QDomElement e = params.item(i).toElement();
if (!e.hasAttribute(QStringLiteral("value")) && e.attribute(QStringLiteral("paramlist")) != QLatin1String("%lumaPaths")) {
if (!e.hasAttribute(QStringLiteral("value")) && e.attribute(QStringLiteral("type")) != QLatin1String("animatedrect") && e.attribute(QStringLiteral("paramlist")) != QLatin1String("%lumaPaths")) {
e.setAttribute(QStringLiteral("value"), e.attribute(QStringLiteral("default")));
}
}
......
......@@ -782,7 +782,7 @@ void initEffects::fillTransitionsList(Mlt::Repository *repository, EffectsList *
paramList.append(quickParameterFill(ret, i18n("Rotate Z"), QStringLiteral("rotate_z"), QStringLiteral("addedgeometry"), QStringLiteral("0"), QStringLiteral("-1800"), QStringLiteral("1800"), QString(), QString(), QStringLiteral("10")));
/*paramList.append(quickParameterFill(ret, i18n("Rotate Y"), "rotate_y", "simplekeyframe", "0", "-1800", "1800", QString(), QString(), "10"));
paramList.append(quickParameterFill(ret, i18n("Rotate Z"), "rotate_z", "simplekeyframe", "0", "-1800", "1800", QString(), QString(), "10"));*/
paramList.append(quickParameterFill(ret, i18n("Fix Shear Y"), QStringLiteral("shear_y"), QStringLiteral("double"), QStringLiteral("0"), QStringLiteral("0"), QStringLiteral("360")));
paramList.append(quickParameterFill(ret, i18n("Fix Shear X"), QStringLiteral("shear_x"), QStringLiteral("double"), QStringLiteral("0"), QStringLiteral("0"), QStringLiteral("360")));
paramList.append(quickParameterFill(ret, i18n("Fix Shear Z"), QStringLiteral("shear_z"), QStringLiteral("double"), QStringLiteral("0"), QStringLiteral("0"), QStringLiteral("360")));
......@@ -873,7 +873,7 @@ void initEffects::parseTransitionFile(EffectsList *transitionList, const QString
effects = doc.elementsByTagName(QStringLiteral("transition"));
int i = effects.count();
if (i == 0) {
qDebug() << "+++++++++++++\nEffect broken: " << name<<"\n+++++++++++";;
qDebug() << "+++++++++++++Transition broken: " << name<<"\n+++++++++++";;
return;
}
......
......@@ -170,7 +170,7 @@ void MyTextItem::updateGeometry(int, int, int)
double offset = (bounding.width() - metrics.width(line)) / 2;
linePath.translate(offset, 0);
} else if ( m_alignment == Qt::AlignRight ) {
double offset = (bounding.width() - metrics.width(line));
double offset = bounding.width() - metrics.width(line);
linePath.translate(offset, 0);
}
m_path.addPath(linePath);
......
......@@ -627,6 +627,9 @@ void AnimationWidget::addParameter(const QDomElement &e)
keyframes = e.attribute(QStringLiteral("value"));
} else {
keyframes = getDefaultKeyframes(e.attribute(QStringLiteral("default")));
if (keyframes.contains('%')) {
keyframes = EffectsController::getStringRectEval(m_monitor->profileInfo(), keyframes);
}
}
QString paramTag = e.attribute(QStringLiteral("name"));
m_animProperties.set(paramTag.toUtf8().constData(), keyframes.toUtf8().constData());
......
......@@ -33,6 +33,7 @@
#include "dialogs/profilesdialog.h"
#include "doc/kthumb.h"
#include "utils/KoIconUtils.h"
#include "timeline/transitionhandler.h"
#include "klocalizedstring.h"
#include <KRecentDirs>
......@@ -1707,7 +1708,7 @@ void Monitor::buildSplitEffect(Mlt::Producer *original, int pos)
warningMessage(i18n("The scal0tilt filter is required for that feature, please install frei0r and restart Kdenlive"));
return;
}
QString splitTransition = KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend";
QString splitTransition = TransitionHandler::compositeTransition();
Mlt::Transition t(*profile(), splitTransition.toUtf8().constData());
if (!t.is_valid()) {
delete m_splitEffect;
......
......@@ -34,6 +34,7 @@
#include "timeline/clip.h"
#include "monitor/glwidget.h"
#include "mltcontroller/clipcontroller.h"
#include "timeline/transitionhandler.h"
#include <mlt++/Mlt.h>
#include <QDebug>
......@@ -1432,7 +1433,8 @@ QList <TransitionInfo> Render::mltInsertTrack(int ix, const QString &name, bool
// Track was inserted as lowest video track, it should not have a composite, but previous lowest should
ix = lowestVideoTrack + 1;
}
Mlt::Transition composite(*m_qmlView->profile(), KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend");
QString comp = TransitionHandler::compositeTransition();
Mlt::Transition composite(*m_qmlView->profile(), comp.toUtf8().constData());
if (composite.is_valid()) {
composite.set("a_track", ix - 1);
composite.set("b_track", ix);
......
......@@ -3128,6 +3128,7 @@ void CustomTrackView::dropEvent(QDropEvent * event)
else
updateTrackDuration(info.track, addCommand);
// TODO: disabled when qtblend transition is fully implemented
if (item->binClip()->isTransparent() && getTransitionItemAtStart(info.startPos, info.track) == NULL) {
// add transparency transition if space is available
if (canBePastedTo(info, TransitionWidget)) {
......@@ -3523,12 +3524,13 @@ void CustomTrackView::addTrack(const TrackInfo &type, int ix)
Mlt::Tractor *tractor = m_document->renderer()->lockService();
// When adding a track, MLT sometimes incorrectly updates transition's tracks
if (ix < m_timeline->tracksCount()) {
Mlt::Transition *tr = m_timeline->transitionHandler->getTransition(KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend", ix+1, ix - 1, true);
Mlt::Transition *tr = m_timeline->transitionHandler->getTrackTransition(QStringList() << QStringLiteral("qtblend") << QStringLiteral("frei0r.cairoblend") << QStringLiteral("movit.overlay"), ix+1, ix - 1);
if (tr) {
tr->set_tracks(ix, ix + 1);
delete tr;
}
}
// TODO: disable updatecomposite with qtblend
// Check we have composite transitions where necessary
m_timeline->updateComposites();
m_document->renderer()->unlockService(tractor);
......@@ -3587,11 +3589,11 @@ void CustomTrackView::removeTrack(int ix)
Mlt::Tractor *tractor = m_document->renderer()->lockService();
QScopedPointer<Mlt::Field> field(tractor->field());
if (m_timeline->getTrackInfo(ix).type == VideoTrack) {
QScopedPointer<Mlt::Transition> tr(m_timeline->transitionHandler->getTransition(KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend", ix, -1, true));
QScopedPointer<Mlt::Transition> tr(m_timeline->transitionHandler->getTrackTransition(QStringList() << QStringLiteral("qtblend") << QStringLiteral("frei0r.cairoblend") << QStringLiteral("movit.overlay"), ix, -1));
if (tr) {
field->disconnect_service(*tr.data());
}
QScopedPointer<Mlt::Transition> mixTr(m_timeline->transitionHandler->getTransition(QStringLiteral("mix"), ix, -1, true));
QScopedPointer<Mlt::Transition> mixTr(m_timeline->transitionHandler->getTrackTransition(QStringList() << QStringLiteral("mix"), ix, -1));
if (mixTr) {
field->disconnect_service(*mixTr.data());
}
......@@ -3630,6 +3632,7 @@ void CustomTrackView::removeTrack(int ix)
// Delete track in MLT playlist
tractor->remove_track(ix);
// TODO: disable updatecomposite with qtblend
// Make sure lowest video track has no composite
m_timeline->updateComposites();
m_document->renderer()->unlockService(tractor);
......
......@@ -756,7 +756,6 @@ bool KeyframeView::loadKeyframes(const QLocale locale, QDomElement effect, int c
if (value.isEmpty()) {
value = e.attribute(QStringLiteral("default"));
}
switch (m_keyframeType) {
case GeometryKeyframe:
m_keyProperties.set(paramName.toUtf8().constData(), value.toUtf8().constData());
......
......@@ -338,7 +338,7 @@ int Timeline::getTracks() {
offset += track->count();
if (audio == 0 && !isBackgroundBlackTrack) {
// Check if we have a composite transition for this track
QScopedPointer<Mlt::Transition> transition(transitionHandler->getTransition(KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend", i, -1, true));
QScopedPointer<Mlt::Transition> transition(transitionHandler->getTrackTransition(QStringList() << QStringLiteral("qtblend") << QStringLiteral("frei0r.cairoblend") << QStringLiteral("movit.overlay"), i, -1));
if (!transition) {
tk->trackHeader->disableComposite();
}
......@@ -393,7 +393,7 @@ void Timeline::getTransitions() {
//skip automatic mix
if (prop.get_int("internal_added") == 237) {
QString trans = prop.get("mlt_service");
if (trans == QLatin1String("movit.overlay") || trans == QLatin1String("frei0r.cairoblend")) {
if (trans == QLatin1String("qtblend") || trans == QLatin1String("movit.overlay") || trans == QLatin1String("frei0r.cairoblend")) {
int ix = prop.get_int("b_track");
if (ix >= 0 && ix < m_tracks.count()) {
TrackInfo info = track(ix)->info();
......@@ -790,9 +790,10 @@ void Timeline::doSwitchTrackVideo(int ix, bool hide)
void Timeline::slotSwitchTrackComposite(int trackIndex, bool enable)
{
if (trackIndex < 1 || trackIndex > m_tracks.count()) return;
QScopedPointer<Mlt::Transition> transition(transitionHandler->getTransition(KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend", trackIndex, -1, true));
QScopedPointer<Mlt::Transition> transition(transitionHandler->getTrackTransition(QStringList() << QStringLiteral("qtblend") << QStringLiteral("frei0r.cairoblend") << QStringLiteral("movit.overlay"), trackIndex, -1));
if (transition) {
transition->set("disable", enable);
// TODO: disable updatecomposite with qtblend
// When turning a track composite on/off, we need to re-plug transitions correctly
updateComposites();
m_doc->renderer()->doRefresh();
......@@ -1729,7 +1730,7 @@ bool Timeline::createOverlay(Mlt::Filter *filter, int tk, int startPos)
trac.set_track(*clipProducer, 0);
trac.set_track(*cln, 1);
cln->attach(*filter);
QString splitTransition = KdenliveSettings::gpu_accel() ? "movit.overlay" : "frei0r.cairoblend";
QString splitTransition = transitionHandler->compositeTransition();
Mlt::Transition t(*m_tractor->profile(), splitTransition.toUtf8().constData());
t.set("always_active", 1);
trac.plant_transition(t, 0, 1);
......
......@@ -19,7 +19,9 @@
#include "transitionhandler.h"
#include "mltcontroller/effectscontroller.h"
#include "mainwindow.h"
#include "kdenlivesettings.h"
TransitionHandler::TransitionHandler(Mlt::Tractor *tractor) : QObject()
, m_tractor(tractor)
......@@ -99,6 +101,12 @@ QMap<QString, QString> TransitionHandler::getTransitionParamsFromXml(const QDomE
}
}
} else {
if (defaultValue.contains(QLatin1Char('%'))) {
ProfileInfo pInfo;
pInfo.profileSize = QSize(m_tractor->profile()->width(), m_tractor->profile()->height());
pInfo.profileFps = m_tractor->profile()->fps();
defaultValue = EffectsController::getStringRectEval(pInfo, defaultValue);
}
map[name] = defaultValue;
}
}
......@@ -412,6 +420,25 @@ Mlt::Transition *TransitionHandler::getTransition(const QString &name, int b_tra
return 0;
}
Mlt::Transition *TransitionHandler::getTrackTransition(const QStringList names, int b_track, int a_track) const
{
QScopedPointer<Mlt::Service> service(m_tractor->field());
while (service && service->is_valid()) {
if (service->type() == transition_type) {
Mlt::Transition t((mlt_transition) service->get_service());
int internal = t.get_int("internal_added");
if (internal >= 200) {
QString service = t.get("mlt_service");
if (names.contains(service) && t.get_b_track() == b_track && (a_track == -1 || t.get_a_track() == a_track)) {
return new Mlt::Transition(t);
}
}
}
service.reset(service->producer());
}
return 0;
}
void TransitionHandler::duplicateTransitionOnPlaylist(int in, int out, QString tag, QDomElement xml, int a_track, int b_track, Mlt::Field *field)
{
QMap<QString, QString> args = getTransitionParamsFromXml(xml);
......@@ -446,6 +473,7 @@ void TransitionHandler::enableMultiTrack(bool enable)
// we need at leas 3 tracks (black bg track + 2 tracks to use this)
return;
}
QStringList compositeService { QStringLiteral("qtblend"), QStringLiteral("frei0r.cairoblend"), QStringLiteral("movit.overlay") };
QScopedPointer<Mlt::Service> service(m_tractor->field());
QScopedPointer<Mlt::Field> field(m_tractor->field());
field->lock();
......@@ -460,7 +488,7 @@ void TransitionHandler::enableMultiTrack(bool enable)
int added = transition.get_int("internal_added");
if (added == 237) {
QString mlt_service = transition.get("mlt_service");
if (mlt_service == QLatin1String("frei0r.cairoblend") && transition.get_int("disable") == 0) {
if (compositeService.contains(mlt_service) && transition.get_int("disable") == 0) {
transition.set("disable", 1);
transition.set("split_disable", 1);
}
......@@ -514,7 +542,7 @@ void TransitionHandler::enableMultiTrack(bool enable)
} else if (added == 237) {
// re-enable track compositing
QString mlt_service = transition.get("mlt_service");
if (mlt_service == QLatin1String("frei0r.cairoblend") && transition.get_int("split_disable") == 1) {
if (compositeService.contains(mlt_service) && transition.get_int("split_disable") == 1) {
transition.set("disable", 0);
transition.set("split_disable", (char*) NULL);
}
......@@ -530,6 +558,7 @@ void TransitionHandler::enableMultiTrack(bool enable)
void TransitionHandler::rebuildComposites(int lowestVideoTrack)
{
QList <Mlt::Transition *>composites;
QStringList compositeService { QStringLiteral("qtblend"), QStringLiteral("frei0r.cairoblend"), QStringLiteral("movit.overlay") };
QList <int> disabled;
QScopedPointer<Mlt::Service> service(m_tractor->field());
Mlt::Field *field = m_tractor->field();
......@@ -540,7 +569,7 @@ void TransitionHandler::rebuildComposites(int lowestVideoTrack)
int internal = t.get_int("internal_added");
if (internal == 237) {
QString service = t.get("mlt_service");
if (service == QLatin1String("frei0r.cairoblend") || service == QLatin1String("movit.overlay")) {
if (compositeService.contains(service)) {
composites << new Mlt::Transition(t);
if (t.get_int("disable") == 1) {
disabled << t.get_int("b_track");
......@@ -573,3 +602,14 @@ void TransitionHandler::rebuildComposites(int lowestVideoTrack)
delete field;
qDeleteAll(composites);
}
// static
const QString TransitionHandler::compositeTransition()
{
if (KdenliveSettings::gpu_accel())
return QStringLiteral("movit.overlay");
if (MainWindow::transitions.hasTransition(QStringLiteral("qtblend"))) {
return QStringLiteral("qtblend");
}
return QStringLiteral("frei0r.cairoblend");
}
......@@ -54,6 +54,10 @@ public:
void enableMultiTrack(bool enable);
/** @brief Plug composite transitions depending on the en/disabled states. */
void rebuildComposites(int lowestVideoTrack);
/** @brief Returns internal track transition. */
Mlt::Transition *getTrackTransition(const QStringList names, int b_track, int a_track) const;
/** @brief Returns the matching composite transition depending on the current settings. */
static const QString compositeTransition();
private:
Mlt::Tractor *m_tractor;
......
......@@ -585,7 +585,7 @@
<bool>true</bool>
</property>
<property name="minimum">
<number>-100</number>
<number>-1000</number>
</property>
<property name="maximum">
<number>1000</number>
......@@ -650,14 +650,14 @@
<property name="flat">
<bool>false</bool>
</property>
<property name="color" stdset="0">
<property name="color">
<color>
<red>85</red>
<green>170</green>
<blue>255</blue>
</color>
</property>
<property name="defaultColor" stdset="0">
<property name="defaultColor">
<color>
<red>0</red>
<green>0</green>
......@@ -763,14 +763,14 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="color" stdset="0">
<property name="color">
<color alpha="100">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="alphaChannelEnabled" stdset="0">
<property name="alphaChannelEnabled">
<bool>true</bool>
</property>
</widget>
......@@ -833,14 +833,14 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="color" stdset="0">
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="defaultColor" stdset="0">
<property name="defaultColor">
<color>
<red>0</red>
<green>0</green>
......@@ -898,14 +898,14 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="color" stdset="0">
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="defaultColor" stdset="0">
<property name="defaultColor">
<color>
<red>0</red>
<green>0</green>
......@@ -1003,14 +1003,14 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="color" stdset="0">
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="defaultColor" stdset="0">
<property name="defaultColor">
<color>
<red>0</red>
<green>0</green>
......@@ -1337,16 +1337,16 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
<customwidget>
<class>KColorButton</class>
<extends>QPushButton</extends>
<header>kcolorbutton.h</header>
</customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment