]> git.sesse.net Git - kdenlive/blob - src/effectstack/collapsiblegroup.cpp
New widget for effect group
[kdenlive] / src / effectstack / collapsiblegroup.cpp
1 /***************************************************************************
2  *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20
21 #include "collapsiblegroup.h"
22
23
24 #include <QMenu>
25 #include <QVBoxLayout>
26 #include <QInputDialog>
27 #include <QDragEnterEvent>
28 #include <QDropEvent>
29
30 #include <KDebug>
31 #include <KGlobalSettings>
32 #include <KLocale>
33 #include <KMessageBox>
34 #include <KStandardDirs>
35 #include <KFileDialog>
36 #include <KUrlRequester>
37 #include <KColorScheme>
38
39
40 CollapsibleGroup::CollapsibleGroup(int ix, bool firstGroup, bool lastGroup, QWidget * parent) :
41         AbstractCollapsibleWidget(parent),
42         m_index(ix)
43 {
44     setupUi(this);
45     setFont(KGlobalSettings::smallestReadableFont());
46    
47     buttonUp->setIcon(KIcon("kdenlive-up"));
48     buttonUp->setToolTip(i18n("Move effect up"));
49     buttonDown->setIcon(KIcon("kdenlive-down"));
50     buttonDown->setToolTip(i18n("Move effect down"));
51
52     buttonDel->setIcon(KIcon("kdenlive-deleffect"));
53     buttonDel->setToolTip(i18n("Delete effect"));
54     if (firstGroup) buttonUp->setVisible(false);
55     if (lastGroup) buttonDown->setVisible(false);
56     m_menu = new QMenu;
57     m_menu->addAction(KIcon("view-refresh"), i18n("Reset effect"), this, SLOT(slotResetEffect()));
58     m_menu->addAction(KIcon("document-save"), i18n("Save effect"), this, SLOT(slotSaveEffect()));
59     
60     title->setText(i18n("Effect Group"));
61     effecticon->setPixmap(KIcon("folder").pixmap(16,16));
62     m_menu->addAction(KIcon("list-remove"), i18n("Ungroup"), this, SLOT(slotUnGroup()));
63     setAcceptDrops(true);
64     menuButton->setIcon(KIcon("kdenlive-menu"));
65     menuButton->setMenu(m_menu);
66     
67     enabledBox->setChecked(true);
68
69     connect(collapseButton, SIGNAL(clicked()), this, SLOT(slotSwitch()));
70     connect(enabledBox, SIGNAL(toggled(bool)), this, SLOT(slotEnable(bool)));
71     connect(buttonUp, SIGNAL(clicked()), this, SLOT(slotEffectUp()));
72     connect(buttonDown, SIGNAL(clicked()), this, SLOT(slotEffectDown()));
73     connect(buttonDel, SIGNAL(clicked()), this, SLOT(slotDeleteEffect()));
74
75 }
76
77 CollapsibleGroup::~CollapsibleGroup()
78 {
79     delete m_menu;
80 }
81
82 void CollapsibleGroup::slotUnGroup()
83 {
84     emit unGroup(this);
85 }
86
87 bool CollapsibleGroup::isActive() const
88 {
89     return decoframegroup->property("active").toBool();
90 }
91
92 void CollapsibleGroup::setActive(bool activate)
93 {
94     decoframegroup->setProperty("active", activate);
95     decoframegroup->setStyleSheet(decoframegroup->styleSheet());
96 }
97
98 void CollapsibleGroup::mouseDoubleClickEvent ( QMouseEvent * event )
99 {
100     if (frame->underMouse() && collapseButton->isEnabled()) slotSwitch();
101     QWidget::mouseDoubleClickEvent(event);
102 }
103
104
105 void CollapsibleGroup::slotEnable(bool enable)
106 {
107     title->setEnabled(enable);
108     enabledBox->blockSignals(true);
109     enabledBox->setChecked(enable);
110     enabledBox->blockSignals(false);
111     QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout());
112     if (vbox == NULL) return;
113     for (int i = 0; i < vbox->count(); i++) {
114         CollapsibleGroup *e = static_cast<CollapsibleGroup *>(vbox->itemAt(i)->widget());
115         if (e) e->enabledBox->setChecked(enable);// slotEnable(enable);
116     }
117 }
118
119 void CollapsibleGroup::slotDeleteEffect()
120 {
121     emit deleteGroup(groupIndex());
122 }
123
124 void CollapsibleGroup::slotEffectUp()
125 {
126     emit changeGroupPosition(groupIndex(), true);
127 }
128
129 void CollapsibleGroup::slotEffectDown()
130 {
131     emit changeGroupPosition(groupIndex(), false);
132 }
133
134 void CollapsibleGroup::slotSaveEffect()
135 {
136     QString name = QInputDialog::getText(this, i18n("Save Effect"), i18n("Name for saved effect: "));
137     if (name.isEmpty()) return;
138     QString path = KStandardDirs::locateLocal("appdata", "effects/", true);
139     path = path + name + ".xml";
140     if (QFile::exists(path)) if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", path)) == KMessageBox::No) return;
141
142     /*TODO
143     QDomDocument doc;
144     QDomElement effect = m_effect.cloneNode().toElement();
145     doc.appendChild(doc.importNode(effect, true));
146     effect = doc.firstChild().toElement();
147     effect.removeAttribute("kdenlive_ix");
148     effect.setAttribute("id", name);
149     effect.setAttribute("type", "custom");
150     QDomElement effectname = effect.firstChildElement("name");
151     effect.removeChild(effectname);
152     effectname = doc.createElement("name");
153     QDomText nametext = doc.createTextNode(name);
154     effectname.appendChild(nametext);
155     effect.insertBefore(effectname, QDomNode());
156     QDomElement effectprops = effect.firstChildElement("properties");
157     effectprops.setAttribute("id", name);
158     effectprops.setAttribute("type", "custom");
159
160     QFile file(path);
161     if (file.open(QFile::WriteOnly | QFile::Truncate)) {
162         QTextStream out(&file);
163         out << doc.toString();
164     }
165     file.close();
166     emit reloadEffects();*/
167 }
168
169 void CollapsibleGroup::slotResetEffect()
170 {
171     //TODO: emit resetEffect(effectIndex());
172 }
173
174 void CollapsibleGroup::slotSwitch()
175 {
176     bool enable = !widgetFrame->isVisible();
177     slotShow(enable);
178 }
179
180 void CollapsibleGroup::slotShow(bool show)
181 {
182     widgetFrame->setVisible(show);
183     if (show) {
184         collapseButton->setArrowType(Qt::DownArrow);
185         m_info.isCollapsed = false;
186     }
187     else {
188         collapseButton->setArrowType(Qt::RightArrow);
189         m_info.isCollapsed = true;
190     }
191     //emit parameterChanged(m_original_effect, m_effect, effectIndex());   
192 }
193
194 void CollapsibleGroup::updateGroupIndex(int groupIndex)
195 {
196   /*TODO:
197     m_info.groupIndex = groupIndex;
198     m_effect.setAttribute("kdenlive_info", m_info.toString());
199     emit parameterChanged(m_original_effect, m_effect, effectIndex());*/
200 }
201
202 void CollapsibleGroup::addGroupEffect(CollapsibleEffect *effect)
203 {
204     QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout());
205     if (vbox == NULL) {
206         vbox = new QVBoxLayout();
207         vbox->setContentsMargins(10, 0, 0, 0);
208         vbox->setSpacing(2);
209         widgetFrame->setLayout(vbox);
210     }
211     effect->setGroupIndex(groupIndex());
212     vbox->addWidget(effect);
213 }
214
215 QString CollapsibleGroup::infoString() const
216 {
217     return m_info.toString();
218 }
219
220 void CollapsibleGroup::removeGroup(int ix, QVBoxLayout *layout)
221 {
222     QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout());
223     if (vbox == NULL) return;
224     
225     for (int j = vbox->count() - 1; j >= 0; j--) {
226         QLayoutItem *child = vbox->takeAt(j);
227         CollapsibleGroup *e = static_cast<CollapsibleGroup *>(child->widget());
228         layout->insertWidget(ix, e);
229         e->updateGroupIndex(-1);
230         delete child;
231     }
232 }
233
234 int CollapsibleGroup::groupIndex() const
235 {
236     return m_index;
237 }
238
239
240
241 bool CollapsibleGroup::isGroup() const
242 {
243     return true;
244 }
245
246 void CollapsibleGroup::updateTimecodeFormat()
247 {
248     QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout());
249     if (vbox == NULL) return;
250     for (int j = vbox->count() - 1; j >= 0; j--) {
251         CollapsibleEffect *e = static_cast<CollapsibleEffect *>(vbox->itemAt(j)->widget());
252         if (e) e->updateTimecodeFormat();
253     }
254 }
255
256 void CollapsibleGroup::dragEnterEvent(QDragEnterEvent *event)
257 {
258     if (event->mimeData()->hasFormat("kdenlive/effectslist")) {
259         frame->setProperty("active", true);
260         frame->setStyleSheet(frame->styleSheet());
261         event->acceptProposedAction();
262     }
263 }
264
265 void CollapsibleGroup::dragLeaveEvent(QDragLeaveEvent */*event*/)
266 {
267     frame->setProperty("active", false);
268     frame->setStyleSheet(frame->styleSheet());
269 }
270
271 void CollapsibleGroup::dropEvent(QDropEvent *event)
272 {
273     frame->setProperty("active", false);
274     frame->setStyleSheet(frame->styleSheet());
275     const QString effects = QString::fromUtf8(event->mimeData()->data("kdenlive/effectslist"));
276     //event->acceptProposedAction();
277     QDomDocument doc;
278     doc.setContent(effects, true);
279     QDomElement e = doc.documentElement();
280     int ix = e.attribute("kdenlive_ix").toInt();
281     if (ix == 0) {
282         // effect dropped from effects list, add it
283         e.setAttribute("kdenlive_ix", ix);
284         event->setDropAction(Qt::CopyAction);
285         event->accept();
286         emit addEffect(e);
287         return;
288     }
289     int new_index = -1;
290     QVBoxLayout *vbox = static_cast<QVBoxLayout *>(widgetFrame->layout());
291     if (vbox == NULL) return;
292     CollapsibleEffect *effect = static_cast<CollapsibleEffect *>(vbox->itemAt(vbox->count() -1)->widget());
293     new_index = effect->effectIndex();
294     emit moveEffect(ix, new_index, m_index);
295     event->setDropAction(Qt::MoveAction);
296     event->accept();
297 }
298