* Fix possible crash when creating new document

* Add "Cancel" button that will abort loading when opening a project with missing clips:
http://www.kdenlive.org:80/mantis/view.php?id=622

svn path=/branches/KDE4/; revision=3012
parent b8c9e129
......@@ -37,6 +37,15 @@ ClipManager::~ClipManager() {
qDeleteAll(m_clipList);
}
void ClipManager::clear() {
qDeleteAll(m_clipList);
m_clipList.clear();
m_clipIdCounter = 1;
m_folderIdCounter = 1;
m_folderList.clear();
m_audioThumbsQueue.clear();
}
void ClipManager::checkAudioThumbs() {
if (m_audioThumbsEnabled == KdenliveSettings::audiothumbnails()) return;
m_audioThumbsEnabled = KdenliveSettings::audiothumbnails();
......
......@@ -74,6 +74,7 @@ Q_OBJECT public:
void resetProducersList(QList <Mlt::Producer *> prods);
void addFolder(const QString&, const QString&);
void deleteFolder(const QString&);
void clear();
public slots:
void updatePreviewSettings();
......
......@@ -41,7 +41,7 @@
#include "titlewidget.h"
#include "mainwindow.h"
KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QPoint tracks, Render *render, MainWindow *parent): QObject(parent), m_render(render), m_url(url), m_projectFolder(projectFolder), m_commandStack(new QUndoStack(undoGroup)), m_modified(false), m_documentLoadingProgress(0), m_documentLoadingStep(0.0), m_startPos(0), m_zoom(7), m_autosave(NULL), m_zoneStart(0), m_zoneEnd(100) {
KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QPoint tracks, Render *render, MainWindow *parent): QObject(parent), m_render(render), m_url(url), m_projectFolder(projectFolder), m_commandStack(new QUndoStack(undoGroup)), m_modified(false), m_documentLoadingProgress(0), m_documentLoadingStep(0.0), m_startPos(0), m_zoom(7), m_autosave(NULL), m_zoneStart(0), m_zoneEnd(100), m_abortLoading(false) {
m_clipManager = new ClipManager(this);
m_autoSaveTimer = new QTimer(this);
m_autoSaveTimer->setSingleShot(true);
......@@ -92,7 +92,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
setProfilePath(profilePath);
// Build tracks
QString tracks = infoXml.attribute("tracks");
QString xmltracks = infoXml.attribute("tracks");
TrackInfo videoTrack;
videoTrack.type = VIDEOTRACK;
videoTrack.isMute = false;
......@@ -102,8 +102,8 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
audioTrack.type = AUDIOTRACK;
audioTrack.isMute = false;
audioTrack.isBlind = true;
for (int i = 0; i < tracks.size(); i++) {
if (tracks.data()[i] == 'v') m_tracksList.append(videoTrack);
for (int i = 0; i < xmltracks.size(); i++) {
if (xmltracks.data()[i] == 'v') m_tracksList.append(videoTrack);
else m_tracksList.append(audioTrack);
}
......@@ -127,7 +127,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
}
for (int i = 0; i < infomax; i++) {
for (int i = 0; i < infomax && !m_abortLoading; i++) {
e = infoproducers.item(i).cloneNode().toElement();
if (m_documentLoadingStep > 0) {
m_documentLoadingProgress += m_documentLoadingStep;
......@@ -135,7 +135,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
//qApp->processEvents();
}
QString prodId = e.attribute("id");
if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion")) {
if (!e.isNull() && prodId != "black" && !prodId.startsWith("slowmotion") && !m_abortLoading) {
e.setTagName("producer");
// Get MLT's original producer properties
......@@ -151,35 +151,47 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
kDebug() << "// NLIVE PROD: " << prodId;
}
}
QDomNode markers = m_document.elementsByTagName("markers").at(0);
if (!markers.isNull()) {
QDomNodeList markerslist = markers.childNodes();
int maxchild = markerslist.count();
for (int k = 0; k < maxchild; k++) {
e = markerslist.at(k).toElement();
if (e.tagName() == "marker") {
m_clipManager->getClipById(e.attribute("id"))->addSnapMarker(GenTime(e.attribute("time").toDouble()), e.attribute("comment"));
if (m_abortLoading) {
//parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file."), 100);
emit resetProjectList();
m_startPos = 0;
m_url = KUrl();
m_tracksList.clear();
kWarning() << "Aborted loading of: " << url.path();
m_document = createEmptyDocument(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks());
setProfilePath(KdenliveSettings::default_profile());
m_clipManager->clear();
} else {
QDomNode markers = m_document.elementsByTagName("markers").at(0);
if (!markers.isNull()) {
QDomNodeList markerslist = markers.childNodes();
int maxchild = markerslist.count();
for (int k = 0; k < maxchild; k++) {
e = markerslist.at(k).toElement();
if (e.tagName() == "marker") {
m_clipManager->getClipById(e.attribute("id"))->addSnapMarker(GenTime(e.attribute("time").toDouble()), e.attribute("comment"));
}
}
westley.removeChild(markers);
}
westley.removeChild(markers);
m_document.removeChild(infoXmlNode);
kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count();
}
m_document.removeChild(infoXmlNode);
kDebug() << "Reading file: " << url.path() << ", found clips: " << producers.count();
}
} else {
parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file."), 100);
kWarning() << " NO KDENLIVE INFO FOUND IN FILE: " << url.path();
m_document = createEmptyDocument(tracks.x(), tracks.y());
setProfilePath(profileName);
m_document = createEmptyDocument(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks());
m_url = KUrl();
setProfilePath(KdenliveSettings::default_profile());
}
KIO::NetAccess::removeTempFile(tmpFile);
} else {
KMessageBox::error(parent, KIO::NetAccess::lastErrorString());
parent->slotGotProgressInfo(i18n("File %1 is not a Kdenlive project file."), 100);
m_document = createEmptyDocument(tracks.x(), tracks.y());
setProfilePath(profileName);
m_url = KUrl();
m_document = createEmptyDocument(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks());
setProfilePath(KdenliveSettings::default_profile());
}
} else {
m_document = createEmptyDocument(tracks.x(), tracks.y());
......@@ -192,8 +204,7 @@ KdenliveDoc::KdenliveDoc(const KUrl &url, const KUrl &projectFolder, QUndoGroup
KStandardDirs::makeDir(m_projectFolder.path() + "/thumbs/");
KStandardDirs::makeDir(m_projectFolder.path() + "/ladspa/");
m_scenelist = m_document.toString();
kDebug() << "KDEnnlive document, init timecode: " << m_fps;
kDebug() << "KDEnlive document, init timecode: " << m_fps;
if (m_fps == 30000.0 / 1001.0) m_timecode.setFormat(30, true);
else m_timecode.setFormat((int) m_fps);
......@@ -1150,10 +1161,6 @@ QDomNodeList KdenliveDoc::producersList() {
return m_document.elementsByTagName("producer");
}
void KdenliveDoc::backupMltPlaylist() {
if (m_render) m_scenelist = m_render->sceneList();
}
double KdenliveDoc::projectDuration() const {
if (m_render) return GenTime(m_render->getLength(), m_fps).ms() / 1000;
}
......@@ -1241,16 +1248,28 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
const QString size = elem.attribute("file_size");
const QString hash = elem.attribute("file_hash");
QString newpath;
KMessageBox::ButtonCode action = KMessageBox::No;
int action = KMessageBox::No;
if (!size.isEmpty() && !hash.isEmpty()) {
if (!m_searchFolder.isEmpty()) newpath = searchFileRecursively(m_searchFolder, size, hash);
else action = (KMessageBox::ButtonCode)KMessageBox::messageBox(kapp->activeWindow(), KMessageBox::WarningYesNo, i18n("Clip <b>%1</b><br>is invalid, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search automatically")), /*KGuiItem(i18n("Remove from project")), */KGuiItem(i18n("Keep as placeholder")));
else action = (KMessageBox::ButtonCode) KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br>is invalid, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search automatically")), KGuiItem(i18n("Keep as placeholder")));
} else {
if (elem.attribute("type").toInt() == SLIDESHOW) {
if (KMessageBox::messageBox(kapp->activeWindow(), KMessageBox::WarningYesNo, i18n("<qt>Clip <b>%1</b><br>is invalid or missing, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search manually")), /*KGuiItem(i18n("Remove from project")),*/ KGuiItem(i18n("Keep as placeholder"))) == KMessageBox::Yes)
int res = KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br>is invalid or missing, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search manually")), KGuiItem(i18n("Keep as placeholder")));
if (res == KMessageBox::Yes)
newpath = KFileDialog::getExistingDirectory(KUrl("kfiledialog:///clipfolder"), kapp->activeWindow(), i18n("Looking for %1", path));
} else if (KMessageBox::messageBox(kapp->activeWindow(), KMessageBox::WarningYesNo, i18n("Clip <b>%1</b><br>is invalid or missing, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search manually")), /*KGuiItem(i18n("Remove from project")),*/ KGuiItem(i18n("Keep as placeholder"))) == KMessageBox::Yes)
newpath = KFileDialog::getOpenFileName(KUrl("kfiledialog:///clipfolder"), QString(), kapp->activeWindow(), i18n("Looking for %1", path));
else if (res == KMessageBox::Cancel) {
// Abort project loading
action = KMessageBox::Cancel;
}
} else {
int res = KMessageBox::questionYesNoCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br>is invalid or missing, what do you want to do?", path), i18n("File not found"), KGuiItem(i18n("Search manually")), KGuiItem(i18n("Keep as placeholder")));
if (res == KMessageBox::Yes)
newpath = KFileDialog::getOpenFileName(KUrl("kfiledialog:///clipfolder"), QString(), kapp->activeWindow(), i18n("Looking for %1", path));
else if (res == KMessageBox::Cancel) {
// Abort project loading
action = KMessageBox::Cancel;
}
}
}
if (action == KMessageBox::Yes) {
kDebug() << "// ASKED FOR SRCH CLIP: " << clipId;
......@@ -1258,6 +1277,9 @@ void KdenliveDoc::addClip(QDomElement elem, QString clipId, bool createClipItem)
if (!m_searchFolder.isEmpty()) {
newpath = searchFileRecursively(QDir(m_searchFolder), size, hash);
}
} else if (action == KMessageBox::Cancel) {
m_abortLoading = true;
return;
}
if (!newpath.isEmpty()) {
if (elem.attribute("type").toInt() == SLIDESHOW) newpath.append('/' + extension);
......
......@@ -56,7 +56,6 @@ Q_OBJECT public:
int height() const;
KUrl url() const;
KAutoSaveFile *m_autosave;
void backupMltPlaylist();
Timecode timecode() const;
QDomDocument toXml();
//void setRenderer(Render *render);
......@@ -133,7 +132,6 @@ private:
QDomDocument generateSceneList();
ClipManager *m_clipManager;
MltVideoProfile m_profile;
QString m_scenelist;
QTimer *m_autoSaveTimer;
QString m_searchFolder;
/** tells whether current doc has been changed since last save event */
......@@ -142,6 +140,7 @@ private:
KUrl m_projectFolder;
double m_documentLoadingStep;
double m_documentLoadingProgress;
bool m_abortLoading;
int m_zoneStart;
int m_zoneEnd;
......@@ -164,6 +163,7 @@ private slots:
void slotAutoSave();
signals:
void resetProjectList();
void addProjectClip(DocClipBase *, bool getInfo = true);
void signalDeleteProjectClip(const QString &);
void updateClipDisplay(const QString&);
......
......@@ -1519,7 +1519,6 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
kDebug() << "/////////////////// CONNECTING DOC TO PROJECT VIEW ////////////////";
if (m_activeDocument) {
if (m_activeDocument == doc) return;
m_activeDocument->backupMltPlaylist();
if (m_activeTimeline) {
disconnect(m_projectMonitor, SIGNAL(renderPosition(int)), m_activeTimeline, SLOT(moveCursorPos(int)));
disconnect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), m_activeTimeline, SLOT(slotSetZone(QPoint)));
......@@ -1529,6 +1528,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
disconnect(m_activeDocument, SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated()));
disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool)));
disconnect(m_activeDocument, SIGNAL(resetProjectList()), m_projectList, SLOT(slotResetProjectList()));
disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(const QString &)), m_projectList, SLOT(slotDeleteClip(const QString &)));
disconnect(m_activeDocument, SIGNAL(updateClipDisplay(const QString &)), m_projectList, SLOT(slotUpdateClip(const QString &)));
disconnect(m_activeDocument, SIGNAL(selectLastAddedClip(const QString &)), m_projectList, SLOT(slotSelectClip(const QString &)));
......@@ -1583,6 +1583,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), trackView, SLOT(slotSetZone(QPoint)));
connect(m_projectMonitor, SIGNAL(durationChanged(int)), trackView, SLOT(setDuration(int)));
connect(doc, SIGNAL(addProjectClip(DocClipBase *, bool)), m_projectList, SLOT(slotAddClip(DocClipBase *, bool)));
connect(doc, SIGNAL(resetProjectList()), m_projectList, SLOT(slotResetProjectList()));
connect(doc, SIGNAL(signalDeleteProjectClip(const QString &)), m_projectList, SLOT(slotDeleteClip(const QString &)));
connect(doc, SIGNAL(updateClipDisplay(const QString &)), m_projectList, SLOT(slotUpdateClip(const QString &)));
connect(doc, SIGNAL(selectLastAddedClip(const QString &)), m_projectList, SLOT(slotSelectClip(const QString &)));
......
......@@ -131,7 +131,7 @@ void MonitorManager::slotEnd() {
void MonitorManager::resetProfiles(Timecode tc) {
m_timecode = tc;
slotResetProfiles();
QTimer::singleShot(300, this, SLOT(slotResetProfiles()));
}
void MonitorManager::slotResetProfiles() {
......
......@@ -394,6 +394,14 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties) {
listView->blockSignals(false);
}
void ProjectList::slotResetProjectList() {
listView->clear();
emit clipSelected(NULL);
m_thumbnailQueue.clear();
m_infoQueue.clear();
m_refreshed = false;
}
void ProjectList::requestClipInfo(const QDomElement xml, const QString id) {
kDebug() << " PRG LIST REQUEST CLP INFO: " << id;
m_infoQueue.insert(id, xml);
......@@ -498,6 +506,7 @@ void ProjectList::slotRemoveInvalidClip(const QString &id) {
m_doc->deleteProjectClip(ids);
}
if (!m_infoQueue.isEmpty()) QTimer::singleShot(300, this, SLOT(slotProcessNextClipInQueue()));
else listView->setEnabled(true);
}
void ProjectList::slotAddColorClip() {
......@@ -578,6 +587,7 @@ void ProjectList::slotAddTitleClip() {
void ProjectList::setDocument(KdenliveDoc *doc) {
listView->blockSignals(true);
listView->clear();
emit clipSelected(NULL);
m_thumbnailQueue.clear();
m_infoQueue.clear();
m_refreshed = false;
......@@ -666,7 +676,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce
if (item && producer) {
listView->blockSignals(true);
item->setProperties(properties, metadata);
Q_ASSERT_X( item->referencedClip(), "void ProjectList::slotReplyGetFileProperties", QString( "Item with groupName %1 does not have a clip associated" ).arg( item->groupName() ).toLatin1() );
Q_ASSERT_X(item->referencedClip(), "void ProjectList::slotReplyGetFileProperties", QString("Item with groupName %1 does not have a clip associated").arg(item->groupName()).toLatin1());
item->referencedClip()->setProducer(producer);
emit receivedClipDuration(clipId, item->clipMaxDuration());
listView->blockSignals(false);
......
......@@ -130,6 +130,7 @@ public slots:
void slotRemoveClip();
void slotAddClip(KUrl givenUrl = KUrl(), QString group = QString());
void slotAddFolder(const QString foldername, const QString &clipId, bool remove, bool edit = false);
void slotResetProjectList();
private:
ProjectListView *listView;
......@@ -140,7 +141,6 @@ private:
QToolBar *m_toolbar;
QMenu *m_menu;
QUndoStack *m_commandStack;
// mbd: I think this has died at some point: int m_clipIdCounter;
void selectItemById(const QString &clipId);
ProjectItem *getItemById(const QString &id);
ProjectItem *getFolderItemById(const QString &id);
......
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