* NEW: find as you type feature. You can now type a text and the timeline will...

* NEW: find as you type feature. You can now type a text and the timeline will scroll to a clip or marker that has this text
* start fixing bugs in clip's effect index

svn path=/branches/KDE4/; revision=2291
parent e1b746a0
......@@ -124,6 +124,7 @@ void ClipItem::initEffect(QDomElement effect) {
void ClipItem::setKeyframes(const int ix, const QString keyframes) {
QDomElement effect = effectAt(ix);
if (effect.attribute("disabled") == "1") return;
QDomNodeList params = effect.elementsByTagName("parameter");
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
......@@ -148,7 +149,6 @@ void ClipItem::setKeyframes(const int ix, const QString keyframes) {
break;
}
}
}
......@@ -156,25 +156,26 @@ void ClipItem::setSelectedEffect(const int ix) {
m_selectedEffect = ix;
QDomElement effect = effectAt(m_selectedEffect);
QDomNodeList params = effect.elementsByTagName("parameter");
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
if (!e.isNull() && e.attribute("type") == "keyframe") {
m_keyframes.clear();
double max = e.attribute("max").toDouble();
double min = e.attribute("min").toDouble();
m_keyframeFactor = 100.0 / (max - min);
m_keyframeDefault = e.attribute("default").toDouble();
// parse keyframes
QStringList keyframes = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
foreach(QString str, keyframes) {
int pos = str.section(":", 0, 0).toInt();
double val = str.section(":", 1, 1).toDouble();
m_keyframes[pos] = val;
if (effect.attribute("disabled") != "1")
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
if (!e.isNull() && e.attribute("type") == "keyframe") {
m_keyframes.clear();
double max = e.attribute("max").toDouble();
double min = e.attribute("min").toDouble();
m_keyframeFactor = 100.0 / (max - min);
m_keyframeDefault = e.attribute("default").toDouble();
// parse keyframes
QStringList keyframes = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
foreach(QString str, keyframes) {
int pos = str.section(":", 0, 0).toInt();
double val = str.section(":", 1, 1).toDouble();
m_keyframes[pos] = val;
}
update();
return;
}
update();
return;
}
}
if (!m_keyframes.isEmpty()) {
m_keyframes.clear();
update();
......@@ -199,6 +200,7 @@ QString ClipItem::keyframes(const int index) {
void ClipItem::updateKeyframeEffect() {
// regenerate xml parameter from the clip keyframes
QDomElement effect = effectAt(m_selectedEffect);
if (effect.attribute("disabled") == "1") return;
QDomNodeList params = effect.elementsByTagName("parameter");
for (int i = 0; i < params.count(); i++) {
......@@ -591,6 +593,22 @@ QList <GenTime> ClipItem::snapMarkers() const {
return snaps;
}
QList <CommentedTime> ClipItem::commentedSnapMarkers() const {
QList < CommentedTime > snaps;
QList < CommentedTime > markers = baseClip()->commentedSnapMarkers();
GenTime pos;
double framepos;
for (int i = 0; i < markers.size(); i++) {
pos = markers.at(i).time() - cropStart();
if (pos > GenTime()) {
if (pos > duration()) break;
else snaps.append(CommentedTime(pos + startPos(), markers.at(i).comment()));
}
}
return snaps;
}
void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels) {
QRectF re = path.boundingRect();
......
......@@ -79,6 +79,7 @@ public:
void refreshClip();
/** Returns a list of times for this clip's markers */
QList <GenTime> snapMarkers() const;
QList <CommentedTime> commentedSnapMarkers() const;
uint fadeIn() const;
uint fadeOut() const;
void setSelectedEffect(const int ix);
......
This diff is collapsed.
......@@ -65,7 +65,7 @@ public:
void slotAddEffect(QDomElement effect, GenTime pos, int track);
void addEffect(int track, GenTime pos, QDomElement effect);
void deleteEffect(int track, GenTime pos, QDomElement effect);
void updateEffect(int track, GenTime pos, QDomElement effect);
void updateEffect(int track, GenTime pos, QDomElement effect, int ix);
void moveEffect(int track, GenTime pos, int oldPos, int newPos);
void addTransition(ItemInfo transitionInfo, int endTrack, QDomElement params);
void deleteTransition(ItemInfo transitionInfo, int endTrack, QDomElement params);
......@@ -85,15 +85,18 @@ public:
double getSnapPointForPos(double pos);
QDomElement xmlInfo();
void editKeyFrame(const GenTime pos, const int track, const int index, const QString keyframes);
bool findString(const QString &text);
void initSearchStrings();
void clearSearchStrings();
public slots:
void setCursorPos(int pos, bool seek = true);
void moveCursorPos(int delta);
void updateCursorPos();
void slotDeleteEffect(ClipItem *clip, QDomElement effect);
void slotChangeEffectState(ClipItem *clip, QDomElement effect, bool disable);
void slotChangeEffectState(ClipItem *clip, int effectPos, bool disable);
void slotChangeEffectPosition(ClipItem *clip, int currentPos, int newPos);
void slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect);
void slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect, int ix);
void slotRefreshEffects(ClipItem *clip);
void setDuration(int duration);
void slotAddTransition(ClipItem* clip, ItemInfo transitionInfo, int endTrack, QDomElement transition = QDomElement());
......@@ -143,6 +146,7 @@ private:
QPoint m_clickPoint;
QPoint m_clickEvent;
QList <GenTime> m_snapPoints;
QList <CommentedTime> m_searchPoints;
QList <Guide *> m_guides;
void updateSnapPoints(AbstractClipItem *selected);
ClipItem *getClipItemAt(int pos, int track);
......@@ -157,6 +161,7 @@ private:
QMenu *m_timelineContextClipMenu;
QMenu *m_timelineContextTransitionMenu;
QList <TrackInfo> m_tracksList;
QList <CommentedTime> m_searchStrings;
PROJECTTOOL m_tool;
QCursor m_razorCursor;
/** Get the index of the video track that is just below current track */
......
......@@ -21,6 +21,8 @@
#ifndef DEFINITIONS_H
#define DEFINITIONS_H
#include <KLocale>
#include "gentime.h"
#define FRAME_SIZE 90
......@@ -76,4 +78,23 @@ struct MltVideoProfile {
int display_aspect_den;
};
class CommentedTime {
public:
CommentedTime(): t(GenTime(0)) {}
CommentedTime(const GenTime time, QString comment)
: t(time), c(comment) { }
QString comment() const {
return (c.isEmpty() ? i18n("Marker") : c);
}
GenTime time() const {
return t;
}
void setComment(QString comm) {
c = comm;
}
private:
GenTime t;
QString c;
};
#endif
......@@ -28,7 +28,6 @@
#include <QTimer>
#include <KUrl>
#include <klocale.h>
#include "gentime.h"
#include "definitions.h"
......@@ -43,25 +42,7 @@ class KdenliveDoc;
class KThumb;
class ClipManager;
class CommentedTime {
public:
CommentedTime(): t(GenTime(0)) {}
CommentedTime(const GenTime time, QString comment)
: t(time), c(comment) { }
QString comment() const {
return (c.isEmpty() ? i18n("Marker") : c);
}
GenTime time() const {
return t;
}
void setComment(QString comm) {
c = comm;
}
private:
GenTime t;
QString c;
};
class DocClipBase: public QObject {
......
......@@ -22,8 +22,8 @@
#include "editeffectcommand.h"
#include "customtrackview.h"
EditEffectCommand::EditEffectCommand(CustomTrackView *view, const int track, GenTime pos, QDomElement oldeffect, QDomElement effect, bool doIt)
: m_view(view), m_track(track), m_pos(pos), m_oldeffect(oldeffect), m_doIt(doIt) {
EditEffectCommand::EditEffectCommand(CustomTrackView *view, const int track, GenTime pos, QDomElement oldeffect, QDomElement effect, int stackPos, bool doIt)
: m_view(view), m_track(track), m_pos(pos), m_oldeffect(oldeffect), m_stackPos(stackPos), m_doIt(doIt) {
m_effect = effect.cloneNode().toElement();
QString effectName;
QDomNode namenode = effect.elementsByTagName("name").item(0);
......@@ -49,12 +49,12 @@ bool EditEffectCommand::mergeWith(const QUndoCommand * other) {
// virtual
void EditEffectCommand::undo() {
kDebug() << "---- undoing action";
m_view->updateEffect(m_track, m_pos, m_oldeffect);
m_view->updateEffect(m_track, m_pos, m_oldeffect, m_stackPos);
}
// virtual
void EditEffectCommand::redo() {
kDebug() << "---- redoing action";
m_view->updateEffect(m_track, m_pos, m_effect);
m_view->updateEffect(m_track, m_pos, m_effect, m_stackPos);
}
#include "editeffectcommand.moc"
......@@ -30,7 +30,7 @@ class CustomTrackView;
class EditEffectCommand : public QUndoCommand {
public:
EditEffectCommand(CustomTrackView *view, const int track, GenTime pos, QDomElement oldeffect, QDomElement effect, bool doIt);
EditEffectCommand(CustomTrackView *view, const int track, GenTime pos, QDomElement oldeffect, QDomElement effect, int stackPos, bool doIt);
virtual int id() const;
virtual bool mergeWith(const QUndoCommand * command);
......@@ -43,6 +43,7 @@ private:
QDomElement m_effect;
QDomElement m_oldeffect;
const GenTime m_pos;
int m_stackPos;
bool m_doIt;
};
......
......@@ -66,7 +66,7 @@ EffectStackView::EffectStackView(QWidget *parent)
void EffectStackView::slotUpdateEffectParams(const QDomElement& old, const QDomElement& e) {
if (clipref)
emit updateClipEffect(clipref, old, e);
emit updateClipEffect(clipref, old, e, ui.effectlist->currentRow());
}
void EffectStackView::slotClipItemSelected(ClipItem* c) {
......@@ -92,7 +92,7 @@ void EffectStackView::slotItemChanged(QListWidgetItem *item) {
ui.buttonReset->setEnabled(!disable);
int activeRow = ui.effectlist->currentRow();
if (activeRow >= 0) {
emit changeEffectState(clipref, clipref->effectAt(activeRow), disable);
emit changeEffectState(clipref, activeRow, disable);
}
}
......@@ -179,7 +179,7 @@ void EffectStackView::slotResetEffect() {
if (!dom.isNull()) {
dom.setAttribute("kdenlive_ix", old.attribute("kdenlive_ix"));
emit transferParamDesc(dom, 0, 100);//minx max frame
emit updateClipEffect(clipref, old, dom);
emit updateClipEffect(clipref, old, dom, activeRow);
}
}
......
......@@ -54,12 +54,12 @@ signals:
void transferParamDesc(const QDomElement&, int , int);
void removeEffect(ClipItem*, QDomElement);
/** Parameters for an effect changed, update the filter in playlist */
void updateClipEffect(ClipItem*, QDomElement, QDomElement);
void updateClipEffect(ClipItem*, QDomElement, QDomElement, int);
/** An effect in stack was moved, we need to regenerate
all effects for this clip in the playlist */
void refreshEffectStack(ClipItem *);
/** Enable or disable an effect */
void changeEffectState(ClipItem*, QDomElement, bool);
void changeEffectState(ClipItem*, int, bool);
/** An effect in stack was moved */
void changeEffectPosition(ClipItem*, int, int);
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<gui name="kdenlive" version="18">
<gui name="kdenlive" version="19">
<ToolBar name="extraToolBar" >
<text>Extra Toolbar</text>
<Action name="project_render" />
</ToolBar>
<MenuBar>
<Menu name="file" >
<Action name="clear" />
<Menu name="edit" >
<Action name="project_find" />
</Menu>
<Menu name="project" ><text>Project</text>
<Action name="project_render" />
<Action name="project_settings" />
......
......@@ -24,6 +24,7 @@
#include <QAction>
#include <QtTest>
#include <QtCore>
#include <QKeyEvent>
#include <KApplication>
#include <KAction>
......@@ -88,7 +89,7 @@ EffectsList MainWindow::transitions;
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent),
m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL), m_jogProcess(NULL) {
m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL), m_jogProcess(NULL), m_findActivated(false) {
setlocale(LC_NUMERIC, "POSIX");
parseProfiles();
setFont(KGlobalSettings::toolBarFont());
......@@ -105,6 +106,9 @@ MainWindow::MainWindow(QWidget *parent)
m_timelineArea->setCornerWidget(closeTabButton);
connect(m_timelineArea, SIGNAL(currentChanged(int)), this, SLOT(activateDocument()));
connect(&m_findTimer, SIGNAL(timeout()), this, SLOT(findTimeout()));
m_findTimer.setSingleShot(true);
initEffects::parseEffectFiles();
m_monitorManager = new MonitorManager();
......@@ -496,6 +500,10 @@ void MainWindow::setupActions() {
actionCollection()->addAction("snap", m_buttonSnap);
actionCollection()->addAction("zoom_fit", m_buttonFitZoom);
m_projectSearch = new KAction(KIcon("edit-find"), i18n("Find"), this);
actionCollection()->addAction("project_find", m_projectSearch);
connect(m_projectSearch, SIGNAL(triggered(bool)), this, SLOT(slotFind()));
m_projectSearch->setShortcut(Qt::Key_Slash);
KAction* profilesAction = new KAction(KIcon("document-new"), i18n("Manage Profiles"), this);
actionCollection()->addAction("manage_profiles", profilesAction);
......@@ -878,17 +886,17 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
disconnect(m_activeDocument, SIGNAL(refreshClipThumbnail(int)), m_projectList, SLOT(slotRefreshClipThumbnail(int)));
disconnect(m_activeDocument, SIGNAL(deletTimelineClip(int)), m_activeTimeline, SLOT(slotDeleteClip(int)));
disconnect(m_activeTimeline, SIGNAL(clipItemSelected(ClipItem*)), effectStack, SLOT(slotClipItemSelected(ClipItem*)));
disconnect(trackView, SIGNAL(clipItemSelected(ClipItem*)), this, SLOT(slotActivateEffectStackView()));
disconnect(m_activeTimeline, SIGNAL(clipItemSelected(ClipItem*)), this, SLOT(slotActivateEffectStackView()));
disconnect(m_activeTimeline, SIGNAL(transitionItemSelected(Transition*)), transitionConfig, SLOT(slotTransitionItemSelected(Transition*)));
disconnect(trackView, SIGNAL(transitionItemSelected(Transition*)), this, SLOT(slotActivateTransitionView()));
disconnect(m_activeTimeline, SIGNAL(transitionItemSelected(Transition*)), this, SLOT(slotActivateTransitionView()));
disconnect(m_zoomSlider, SIGNAL(valueChanged(int)), m_activeTimeline, SLOT(slotChangeZoom(int)));
disconnect(trackView->projectView(), SIGNAL(displayMessage(const QString&, MessageType)), m_messageLabel, SLOT(setMessage(const QString&, MessageType)));
disconnect(trackView->projectView(), SIGNAL(showClipFrame(DocClipBase *, const int)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, const int)));
disconnect(m_activeTimeline->projectView(), SIGNAL(displayMessage(const QString&, MessageType)), m_messageLabel, SLOT(setMessage(const QString&, MessageType)));
disconnect(m_activeTimeline->projectView(), SIGNAL(showClipFrame(DocClipBase *, const int)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, const int)));
disconnect(m_activeDocument, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
disconnect(effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement)));
disconnect(effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement, int)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement, int)));
disconnect(effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
disconnect(effectStack, SIGNAL(changeEffectState(ClipItem*, QDomElement, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, QDomElement, bool)));
disconnect(effectStack, SIGNAL(changeEffectState(ClipItem*, int, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, bool)));
disconnect(effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
disconnect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
disconnect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
......@@ -929,9 +937,9 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
connect(trackView->projectView(), SIGNAL(showClipFrame(DocClipBase *, const int)), m_clipMonitor, SLOT(slotSetXml(DocClipBase *, const int)));
connect(effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement)));
connect(effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement, int)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement, int)));
connect(effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
connect(effectStack, SIGNAL(changeEffectState(ClipItem*, QDomElement, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, QDomElement, bool)));
connect(effectStack, SIGNAL(changeEffectState(ClipItem*, int, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, bool)));
connect(effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
connect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
connect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
......@@ -1173,4 +1181,74 @@ void MainWindow::slotSetTool(PROJECTTOOL tool) {
}
}
void MainWindow::slotFind() {
m_projectSearch->setEnabled(false);
m_findActivated = true;
m_findString = QString();
TrackView *currentTab = (TrackView *) m_timelineArea->currentWidget();
currentTab->projectView()->initSearchStrings();
statusBar()->showMessage(i18n("Starting -- find text as you type"));
m_findTimer.start(5000);
qApp->installEventFilter(this);
}
void MainWindow::findAhead() {
TrackView *currentTab = (TrackView *) m_timelineArea->currentWidget();
if (currentTab->projectView()->findString(m_findString)) statusBar()->showMessage(i18n("Found : %1", m_findString));
else statusBar()->showMessage(i18n("Not found : %1", m_findString));
}
void MainWindow::findTimeout() {
m_findActivated = false;
m_findString = QString();
statusBar()->showMessage(i18n("Find stopped"), 3000);
TrackView *currentTab = (TrackView *) m_timelineArea->currentWidget();
currentTab->projectView()->clearSearchStrings();
m_projectSearch->setEnabled(true);
removeEventFilter(this);
}
void MainWindow::keyPressEvent(QKeyEvent *ke) {
if (m_findActivated) {
if (ke->key() == Qt::Key_Backspace) {
m_findString = m_findString.left(m_findString.length() - 1);
if (!m_findString.isEmpty()) {
findAhead();
} else {
findTimeout();
}
m_findTimer.start(4000);
ke->accept();
return;
} else if (ke->key() == Qt::Key_Escape) {
findTimeout();
ke->accept();
return;
} else if (ke->key() == Qt::Key_Space || !ke->text().trimmed().isEmpty()) {
m_findString += ke->text();
findAhead();
m_findTimer.start(4000);
ke->accept();
return;
}
} else KXmlGuiWindow::keyPressEvent(ke);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
if (m_findActivated) {
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent* ke = (QKeyEvent*) event;
ke->accept();
return true;
} else return false;
} else {
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
}
#include "mainwindow.moc"
......@@ -26,6 +26,7 @@
#include <QLabel>
#include <QProgressBar>
#include <QEvent>
#include <QTimer>
#include <KXmlGuiWindow>
#include <KTextEdit>
......@@ -68,6 +69,8 @@ public:
protected:
virtual bool queryClose();
virtual void customEvent(QEvent * e);
virtual void keyPressEvent(QKeyEvent *ke);
bool eventFilter(QObject *obj, QEvent *ev);
private:
KTabWidget* m_timelineArea;
......@@ -117,6 +120,7 @@ private:
JogShuttle *m_jogProcess;
KRecentFilesAction *m_fileOpenRecent;
KAction *m_projectSearch;
QAction *m_buttonAudioThumbs;
QAction *m_buttonVideoThumbs;
......@@ -129,11 +133,16 @@ private:
QSlider *m_zoomSlider;
StatusBarMessageLabel *m_messageLabel;
bool m_findActivated;
QString m_findString;
QTimer m_findTimer;
void readOptions();
void saveOptions();
void activateShuttleDevice();
void slotShuttleAction(int code);
void connectDocumentInfo(KdenliveDoc *doc);
void findAhead();
public slots:
void openFile(const KUrl &url);
......@@ -190,6 +199,8 @@ private slots:
void slotSetTool(PROJECTTOOL tool);
void slotSnapForward();
void slotSnapRewind();
void slotFind();
void findTimeout();
};
#endif
......@@ -1227,8 +1227,8 @@ bool Render::mltEditEffect(int track, GenTime position, QMap <QString, QString>
QMap<QString, QString>::Iterator it = args.begin();
if (!args.value("keyframes").isEmpty() || /*it.key().startsWith("#") || */tag.startsWith("ladspa") || tag == "sox" || tag == "autotrack_rectangle") {
// This is a keyframe effect, to edit it, we remove it and re-add it.
bool success = mltRemoveEffect(track, position, index);
if (success) success = mltAddEffect(track, position, args);
mltRemoveEffect(track, position, index);
bool success = mltAddEffect(track, position, args);
return success;
}
......
......@@ -495,4 +495,6 @@ const QString & TrackView::editMode() const {
return m_editMode;
}
#include "trackview.moc"
......@@ -28,6 +28,7 @@
#include <QGraphicsScene>
#include <QGraphicsLineItem>
#include <QDomElement>
#define FRAME_SIZE 90
#include "ui_timeline_ui.h"
......@@ -59,6 +60,7 @@ public:
int currentZoom() const;
int fitZoom() const;
public slots:
void slotDeleteClip(int clipId);
void slotChangeZoom(int factor);
......@@ -90,6 +92,7 @@ private slots:
void slotTransitionItemSelected(Transition*);
void slotRebuildTrackHeaders();
signals:
void mousePosition(int);
void cursorMoved();
......
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