#include "kdenlivedoc.h"
#include "docclipbase.h"
+#include "profilesdialog.h"
+#include "kdenlivesettings.h"
-KdenliveDoc::KdenliveDoc(const KUrl &url, MltVideoProfile profile, QUndoGroup *undoGroup, QWidget *parent): QObject(parent), m_render(NULL), m_url(url), m_profile(profile), m_fps((double)profile.frame_rate_num / profile.frame_rate_den), m_width(profile.width), m_height(profile.height), m_commandStack(new KUndoStack(undoGroup)) {
+KdenliveDoc::KdenliveDoc(const KUrl &url, MltVideoProfile profile, QUndoGroup *undoGroup, QWidget *parent): QObject(parent), m_render(NULL), m_url(url), m_profile(profile), m_fps((double)profile.frame_rate_num / profile.frame_rate_den), m_width(profile.width), m_height(profile.height), m_commandStack(new KUndoStack(undoGroup)), m_modified(false) {
m_clipManager = new ClipManager(this);
if (!url.isEmpty()) {
QString tmpFile;
QFile file(tmpFile);
m_document.setContent(&file, false);
file.close();
+ QDomNode infoXmlNode = m_document.elementsByTagName("kdenlive").at(0);
+ if (!infoXmlNode.isNull()) {
+ QDomElement infoXml = infoXmlNode.toElement();
+ QString profilePath = infoXml.attribute("profile");
+ if (!profilePath.isEmpty()) setProfilePath(profilePath);
+ }
KIO::NetAccess::removeTempFile(tmpFile);
} else {
KMessageBox::error(parent, KIO::NetAccess::lastErrorString());
delete m_clipManager;
}
+QDomElement KdenliveDoc::documentInfoXml() {
+ QDomDocument doc;
+ QDomElement addedXml = doc.createElement("kdenlive");
+ addedXml.setAttribute("version", "0.7");
+ addedXml.setAttribute("profile", profilePath());
+ return addedXml;
+}
+
+
ClipManager *KdenliveDoc::clipManager() {
return m_clipManager;
}
return m_profile.path;
}
+void KdenliveDoc::setProfilePath(QString path) {
+ KdenliveSettings::setCurrent_profile(path);
+ m_profile = ProfilesDialog::getVideoProfile(path);
+ m_fps = (double) m_profile.frame_rate_num / m_profile.frame_rate_den;
+ m_width = m_profile.width;
+ m_height = m_profile.height;
+ if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true);
+ else m_timecode.setFormat((int) m_fps);
+}
+
void KdenliveDoc::setThumbsProgress(KUrl url, int progress) {
emit thumbsProgress(url, progress);
}
return m_url;
}
+void KdenliveDoc::setUrl(KUrl url) {
+ m_url = url;
+ m_modified = false;
+}
+
QString KdenliveDoc::description() const {
if (m_url.isEmpty())
return i18n("Untitled") + " / " + m_profile.description;
QString description() const;
/** Returns the document format: PAL or NTSC */
QString getDocumentStandard();
+ void setUrl(KUrl url);
+ QDomElement documentInfoXml();
+ void setProfilePath(QString path);
private:
KUrl m_url;
ClipManager *m_clipManager;
MltVideoProfile m_profile;
QString m_scenelist;
+ /** tells whether current doc has been changed since last save event */
+ bool m_modified;
public slots:
#include <kstandarddirs.h>
#include <KUrlRequesterDialog>
#include <KTemporaryFile>
-#include <kuiserverjobtracker.h>
+#include <ktogglefullscreenaction.h>
#include <mlt++/Mlt.h>
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent),
- fileName(QString()), m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL) {
+ m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL) {
parseProfiles();
m_commandStack = new QUndoGroup;
}
}
+void MainWindow::slotFullScreen() {
+ KToggleFullScreenAction::setFullScreen(this, actionCollection()->action("fullscreen")->isChecked());
+}
+
void MainWindow::slotAddEffect(QDomElement effect, GenTime pos, int track) {
if (!m_activeDocument) return;
if (effect.isNull()) {
KStandardAction::redo(this, SLOT(redo()),
actionCollection());
- connect(actionCollection(), SIGNAL(actionHighlighted(QAction*)),
+ KStandardAction::fullScreen(this, SLOT(slotFullScreen()), this, actionCollection());
+
+ connect(actionCollection(), SIGNAL(actionHovered(QAction*)),
this, SLOT(slotDisplayActionMessage(QAction*)));
//connect(actionCollection(), SIGNAL( clearStatusText() ),
//statusBar(), SLOT( clear() ) );
}
void MainWindow::saveFileAs(const QString &outputFileName) {
- KSaveFile file(outputFileName);
- file.open();
-
- QByteArray outputByteArray;
- //outputByteArray.append(textArea->toPlainText());
- file.write(outputByteArray);
- file.finalize();
- file.close();
-
- fileName = outputFileName;
+ m_projectMonitor->saveSceneList(outputFileName, m_activeDocument->documentInfoXml());
+ m_activeDocument->setUrl(KUrl(outputFileName));
+ setCaption(m_activeDocument->description());
+ m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
+ m_timelineArea->setTabToolTip(m_timelineArea->currentIndex(), m_activeDocument->url().path());
}
void MainWindow::saveFileAs() {
- saveFileAs(KFileDialog::getSaveFileName());
+ QString outputFile = KFileDialog::getSaveFileName();
+ if (QFile::exists(outputFile)) {
+ if (KMessageBox::questionYesNo(this, i18n("File already exists.\nDo you want to overwrite it ?")) == KMessageBox::No) return;
+ }
+ saveFileAs(outputFile);
}
void MainWindow::saveFile() {
- if (!fileName.isEmpty()) {
- saveFileAs(fileName);
- } else {
+ if (!m_activeDocument) return;
+ if (m_activeDocument->url().isEmpty()) {
saveFileAs();
+ } else {
+ saveFileAs(m_activeDocument->url().path());
}
}
void MainWindow::slotEditProjectSettings() {
ProjectSettings *w = new ProjectSettings;
- w->exec();
+ if (w->exec() == QDialog::Accepted) {
+ QString profile = w->selectedProfile();
+ m_activeDocument->setProfilePath(profile);
+ m_monitorManager->resetProfiles(profile);
+ setCaption(m_activeDocument->description());
+ KdenliveSettings::setCurrent_profile(m_activeDocument->profilePath());
+ if (m_renderWidget) m_renderWidget->setDocumentStandard(m_activeDocument->getDocumentStandard());
+ m_monitorManager->setTimecode(m_activeDocument->timecode());
+ m_timelineArea->setTabText(m_timelineArea->currentIndex(), m_activeDocument->description());
+
+ // We need to desactivate & reactivate monitors to get a refresh
+ m_monitorManager->switchMonitors();
+ }
delete w;
}
m_activeTimeline = trackView;
+ KdenliveSettings::setCurrent_profile(doc->profilePath());
if (m_renderWidget) m_renderWidget->setDocumentStandard(doc->getDocumentStandard());
m_monitorManager->setTimecode(doc->timecode());
doc->setRenderer(m_projectMonitor->render);
QProgressBar *statusProgressBar;
QLabel* statusLabel;
void setupActions();
- QString fileName;
KdenliveDoc *m_activeDocument;
TrackView *m_activeTimeline;
MonitorManager *m_monitorManager;
void slotSwitchAudioThumbs();
void slotRenderProject();
void slotDoRender(const QString &dest, const QString &render, const QStringList &avformat_args, bool zoneOnly, bool playAfter);
+ void slotFullScreen();
};
#endif
kDebug() << "/////// BUILDING MONITOR, ID: " << ui.video_frame->winId();
}
+QString Monitor::name() const {
+ return m_name;
+}
+
// virtual
void Monitor::mousePressEvent(QMouseEvent * event) {
slotPlay();
render->resetProfile(prof);
}
-void Monitor::saveSceneList(QString path) {
+void Monitor::saveSceneList(QString path, QDomElement e) {
if (render == NULL) return;
- render->saveSceneList(path);
+ render->saveSceneList(path, e);
}
void Monitor::paintEvent(QPaintEvent * event) {
Monitor(QString name, MonitorManager *manager, QWidget *parent = 0);
Render *render;
void resetProfile(QString prof);
+ QString name() const;
virtual void resizeEvent(QResizeEvent * event);
protected:
void start();
void activateMonitor();
void slotPlay();
- void saveSceneList(QString path);
+ void saveSceneList(QString path, QDomElement e = QDomElement());
signals:
void renderPosition(int);
m_activeMonitor = name;
}
+void MonitorManager::switchMonitors() {
+ if (m_activeMonitor == "clip") {
+ m_clipMonitor->stop();
+ m_projectMonitor->start();
+ m_projectMonitor->raise();
+ m_activeMonitor = m_projectMonitor->name();
+ emit raiseClipMonitor(false);
+ } else {
+ m_projectMonitor->stop();
+ m_clipMonitor->start();
+ m_activeMonitor = m_clipMonitor->name();
+ emit raiseClipMonitor(true);
+ }
+}
+
void MonitorManager::slotPlay() {
if (m_activeMonitor == "clip") m_clipMonitor->slotPlay();
else m_projectMonitor->slotPlay();
}
void MonitorManager::resetProfiles(QString prof) {
- //m_clipMonitor->resetProfile(prof);
+ m_clipMonitor->resetProfile(prof);
m_projectMonitor->resetProfile(prof);
}
Timecode timecode();
void setTimecode(Timecode tc);
void resetProfiles(QString prof);
+ void switchMonitors();
public slots:
void activateMonitor(QString name = QString::null);
QStringList profilesFilter;
profilesFilter << "*";
QString path;
+ bool isCustom = false;
+ if (name.contains('/')) isCustom = true;
- // List the Mlt profiles
- profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
- if (profilesFiles.contains(name)) path = KdenliveSettings::mltpath() + "/" + name;
-
- if (path.isEmpty()) {
+ if (!isCustom) {
+ // List the Mlt profiles
+ profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
+ if (profilesFiles.contains(name)) path = KdenliveSettings::mltpath() + "/" + name;
+ }
+ if (isCustom || path.isEmpty()) {
// List custom profiles
- QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles");
- for (int i = 0; i < customProfiles.size(); ++i) {
- profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files);
- if (profilesFiles.contains(name)) {
- path = customProfiles.at(i) + "/" + name;
- break;
- }
- }
+ path = name;
+ /* QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles");
+ for (int i = 0; i < customProfiles.size(); ++i) {
+ profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files);
+ if (profilesFiles.contains(name)) {
+ path = customProfiles.at(i) + "/" + name;
+ break;
+ }
+ }*/
}
if (path.isEmpty()) return result;
KConfig confFile(path);
- result.path = path;
+ result.path = name;
result.description = confFile.entryMap().value("description");
result.frame_rate_num = confFile.entryMap().value("frame_rate_num").toInt();
result.frame_rate_den = confFile.entryMap().value("frame_rate_den").toInt();
// ffmpeg Header files
extern "C" {
-#include <ffmpeg/avformat.h>
+#include <libavformat/avformat.h>
}
#include <QTimer>
#include <QDir>
m_externalwinid = extid;
m_winid = winid;
m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
- Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "westley-xml", "<westley><playlist><producer mlt_service=\"colour\" colour=\"blue\" /></playlist></westley>");
+ Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "westley-xml", "<westley><playlist><producer mlt_service=\"colour\" colour=\"blue\" in=\"0\" out=\"25\" /></playlist></westley>");
m_mltProducer = producer;
m_mltConsumer->connect(*m_mltProducer);
m_mltProducer->set_speed(0.0);
if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop();
m_mltConsumer->set("refresh", 0);
m_mltConsumer->purge();
- //TODO: we should also rebuild filters and delete existing m_mltProfile
+ delete m_mltConsumer;
+ m_mltConsumer = NULL;
+ QString scene = sceneList();
+ if (m_mltProducer) delete m_mltProducer;
+ m_mltProducer = NULL;
+ if (m_mltProfile) delete m_mltProfile;
+ m_mltProfile = NULL;
- //delete m_mltProfile;
m_mltProfile = new Mlt::Profile((char*) profile.toUtf8().data());
- kDebug() << " ++++++++++ RESET CONSUMER WITH PROFILE: " << m_mltProfile->width();
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile , "sdl_preview"); //consumer;
+ m_mltConsumer->set("resize", 1);
+ m_mltConsumer->set("window_id", m_winid);
+ m_mltConsumer->set("terminate_on_pause", 1);
+ m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+
+ Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "westley-xml", (char *) scene.toUtf8().data());
+ m_mltProducer = producer;
+ m_mltConsumer->connect(*m_mltProducer);
+ m_mltProducer->set_speed(0.0);
+
+ //delete m_mltProfile;
// mlt_properties properties = MLT_CONSUMER_PROPERTIES(m_mltConsumer->get_consumer());
//mlt_profile prof = m_mltProfile->get_profile();
//mlt_properties_set_data(properties, "_profile", prof, 0, (mlt_destructor)mlt_profile_close, NULL);
//mlt_properties_set(properties, "profile", "hdv_1080_50i");
- m_mltConsumer->set("profile", (char *) profile.toUtf8().data());
+ //m_mltConsumer->set("profile", (char *) profile.toUtf8().data());
+ //m_mltProfile = new Mlt::Profile((char*) profile.toUtf8().data());
+ kDebug() << " ++++++++++ RESET CONSUMER WITH PROFILE: " << profile << ", WIDTH: " << m_mltProfile->width();
+
//apply_profile_properties( m_mltProfile, m_mltConsumer->get_consumer(), properties );
//refresh();
return 1;
if (m_mltConsumer) {
m_mltConsumer->set("refresh", 0);
- if (!m_mltConsumer->is_stopped()) {
- //emitConsumerStopped();
- m_mltConsumer->stop();
- }
- }
-
+ } else return;
if (m_mltProducer) {
m_mltProducer->set_speed(0.0);
//if (KdenliveSettings::osdtimecode() && m_osdInfo) m_mltProducer->detach(*m_osdInfo);
m_fps = m_mltProducer->get_fps();
emit durationChanged(m_mltProducer->get_playtime());
- //m_connectTimer->start( 500 );
+ //m_connectTimer->start( 1000 );
connectPlaylist();
m_generateScenelist = false;
/** Create the producer from the Westley QDomDocument */
QString Render::sceneList() {
- if (m_winid == -1) return QString();
KTemporaryFile temp;
QString result;
if (temp.open()) {
saveSceneList(temp.fileName());
QFile file(temp.fileName());
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ kWarning() << "++++++++++++++++ CANNOT READ TMP SCENELIST FILE";
return QString();
-
+ }
QTextStream in(&file);
while (!in.atEnd()) {
result.append(in.readLine());
return result;
}
-void Render::saveSceneList(QString path) {
+void Render::saveSceneList(QString path, QDomElement addedXml) {
char *tmppath = decodedString("westley:" + path);
Mlt::Consumer westleyConsumer(*m_mltProfile , tmppath);
delete[] tmppath;
Mlt::Producer prod(m_mltProducer->get_producer());
westleyConsumer.connect(prod);
westleyConsumer.start();
+ if (!addedXml.isNull()) {
+ // add Kdenlive specific tags
+ QFile file(path);
+ QDomDocument doc;
+ doc.setContent(&file, false);
+ doc.documentElement().appendChild(doc.importNode(addedXml, true));
+ file.close();
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ kWarning() << "////// ERROR writing to file: " << path;
+ return;
+ }
+ QTextStream out(&file);
+ out << doc.toString();
+ file.close();
+ }
}
}
void Render::connectPlaylist() {
-
+ if (!m_mltConsumer) return;
m_connectTimer->stop();
+ m_mltConsumer->set("refresh", "0");
m_mltConsumer->connect(*m_mltProducer);
m_mltProducer->set_speed(0.0);
m_mltConsumer->start();
- //refresh();
+ refresh();
/*
if (m_mltConsumer->start() == -1) {
KMessageBox::error(qApp->activeWindow(), i18n("Could not create the video preview window.\nThere is something wrong with your Kdenlive install or your driver settings, please fix it."));
void setSceneList(QDomDocument list, int position = 0);
void setSceneList(QString playlist, int position = 0);
QString sceneList();
- void saveSceneList(QString path);
+ void saveSceneList(QString path, QDomElement addedXml = QDomElement());
/** Wraps the VEML command of the same name. Tells the renderer to
play the current scene at the speed specified, relative to normal