Commit 9faebd37 authored by Jason Wood's avatar Jason Wood

- Added ability to Delete AV File

- Adding, removing and deleting AVFiles is now done via commands - still a little buggy.

As a side effect, KdenliveDoc has had some functionality removed. Namely, any method that is not reversible does not belong in KdenliveDoc. So, movement belongs in KdenliveDoc. CleanProject does not (because you cannot have an "unclean project" method that isn't hideously complicated).

svn path=/trunk/kdenlive/; revision=297
parent f74abaa5
......@@ -27,32 +27,34 @@
#include <qwhatsthis.h>
// include files for KDE
#include <kiconloader.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <kmenubar.h>
#include <kstatusbar.h>
#include <klocale.h>
#include <kconfig.h>
#include <kstdaction.h>
#include <kcommand.h>
#include <kdebug.h>
#include <kkeydialog.h>
#include <kedittoolbar.h>
#include <kfiledialog.h>
#include <kiconloader.h>
#include <kkeydialog.h>
#include <klocale.h>
#include <kmenubar.h>
#include <kmessagebox.h>
#include <kstatusbar.h>
#include <kstdaction.h>
// application specific includes
#include "clippropertiesdialog.h"
#include "docclipbase.h"
#include "effectlistdialog.h"
#include "effectparamdialog.h"
#include "exportdialog.h"
#include "kaddclipcommand.h"
#include "kaddavfilecommand.h"
#include "kdenlive.h"
#include "kdenliveview.h"
#include "kdenlivedoc.h"
#include "kdenlivesetupdlg.h"
#include "kdenliveview.h"
#include "kprogress.h"
#include "krulertimemodel.h"
#include "krendermanager.h"
#include "docclipbase.h"
#include "exportdialog.h"
#include "effectlistdialog.h"
#include "effectparamdialog.h"
#include "clippropertiesdialog.h"
#include "krulertimemodel.h"
#define ID_STATUS_MSG 1
#define ID_EDITMODE_MSG 2
......@@ -775,38 +777,82 @@ void KdenliveApp::slotProjectAddClips()
KURL::List::Iterator it;
KURL url;
KMacroCommand *macroCommand = new KMacroCommand( i18n("Add Clips"));
for(it = urlList.begin(); it != urlList.end(); it++) {
url = (*it);
if(!url.isEmpty()) {
doc->insertAVFile(url);
m_fileDialogPath = url;
Command::KAddAVFileCommand *command;
command = new Command::KAddAVFileCommand(doc, url, true);
macroCommand->addCommand(command);
m_fileDialogPath = url;
}
}
addCommand(macroCommand, true);
m_fileDialogPath.setFileName(QString::null);
m_fileDialogPath.setFileName(QString::null);
slotStatusMsg(i18n("Ready."));
slotStatusMsg(i18n("Ready."));
}
/** Remove clips from the project */
void KdenliveApp::slotProjectDeleteClips()
{
slotStatusMsg(i18n("Removing Clips"));
slotStatusMsg(i18n("Ready."));
slotStatusMsg(i18n("Removing Clips"));
if(KMessageBox::warningContinueCancel(this,
i18n("This will remove all clips on the timeline that are currently using this clip. Are you sure you want to do this?")) == KMessageBox::Continue) {
// Create a macro command that will delete all clips from the timeline involving this
// avfile. Then, delete it.
KMacroCommand *macroCommand = new KMacroCommand( i18n("Delete Project Clip") );
QPtrList<DocClipBase> list = doc->referencedClips(m_projectList->currentSelection());
QPtrListIterator<DocClipBase> itt(list);
while(itt.current())
{
Command::KAddClipCommand *command = new Command::KAddClipCommand(doc, itt.current(), false);
macroCommand->addCommand(command);
++itt;
}
// NOTE - we clear the monitors of the clip here - this does _not_ go into the macro
// command.
m_monitorManager.clearClip(m_projectList->currentSelection());
macroCommand->addCommand(new Command::KAddAVFileCommand(doc, m_projectList->currentSelection(), false));
addCommand(macroCommand, true);
}
slotStatusMsg(i18n("Ready."));
}
/** Cleans the project of unwanted clips */
void KdenliveApp::slotProjectClean()
{
slotStatusMsg(i18n("Cleaning Project"));
slotStatusMsg(i18n("Cleaning Project"));
if(KMessageBox::warningContinueCancel(this,
if(KMessageBox::warningContinueCancel(this,
i18n("Clean Project removes files from the project that are unused.\
Are you sure you want to do this?")) == KMessageBox::Continue) {
doc->cleanAVFileList();
KMacroCommand *macroCommand = new KMacroCommand( i18n("Clean Project") );
QPtrListIterator<AVFile> itt(doc->avFileList());
while(itt.current()) {
QPtrListIterator<AVFile> next = itt;
++itt;
if(next.current()->numReferences()==0) {
macroCommand->addCommand(new Command::KAddAVFileCommand(doc, next.current(), false));
}
}
addCommand(macroCommand, true);
}
slotStatusMsg(i18n("Ready."));
slotStatusMsg(i18n("Ready."));
}
void KdenliveApp::slotProjectClipProperties()
......
......@@ -273,9 +273,9 @@ AVFile *KdenliveDoc::insertAVFile(const KURL &file)
return av;
}
const AVFileList &KdenliveDoc::avFileList()
const AVFileList &KdenliveDoc::avFileList() const
{
return m_fileList;
return m_fileList;
}
/** Returns the number of frames per second. */
......@@ -318,17 +318,16 @@ void KdenliveDoc::slot_insertClips(QPtrList<DocClipBase> clips)
insertAVFile(clip->fileURL());
}
emit avFileListUpdated();
emit avFileListUpdated();
setModified(true);
}
/** Returns a reference to the AVFile matching the url. If no AVFile matching the given url is
found, then one will be created. Either way, the reference count for the AVFile will be incremented
by one, and the file will be returned. */
found, then one will be created. This method is not in charge of incrementing the reference count
of the avfile - this must be done by the calling function. */
AVFile * KdenliveDoc::getAVFileReference(KURL url)
{
AVFile *av = insertAVFile(url);
av->addReference();
return av;
}
......@@ -383,20 +382,6 @@ void KdenliveDoc::setModified(bool state)
}
}
/** Removes entries from the AVFileList which are unreferenced by any clips. */
void KdenliveDoc::cleanAVFileList()
{
QPtrListIterator<AVFile> itt(m_fileList);
while(itt.current()) {
QPtrListIterator<AVFile> next = itt;
++itt;
if(next.current()->numReferences()==0) {
deleteAVFile(next.current());
}
}
}
/** Finds and removes the specified avfile from the document. If there are any
clips on the timeline which use this clip, then they will be deleted as well.
Emits AVFileList changed if successful. */
......@@ -406,19 +391,18 @@ void KdenliveDoc::deleteAVFile(AVFile *file)
if(index!=-1) {
if(file->numReferences() > 0) {
#warning Deleting files with references not yet implemented
kdWarning() << "Cannot delete files with references at the moment " << endl;
return;
kdError() << "Cannot delete a clip that has references!" << endl;
} else {
/** If we delete the clip before removing the pointer to it in the relevant
* AVListViewItem, bad things happen... For some reason, the text method
* gets called after the deletion, even though the very next thing we do
* is to emit an update signal. which removes it.*/
m_fileList.setAutoDelete(false);
m_fileList.removeRef(file);
emit avFileListUpdated();
delete file;
m_fileList.setAutoDelete(true);
}
/** If we delete the clip before removing the pointer to it in the relevant AVListViewItem,
bad things happen... For some reason, the text method gets called after the deletion, even
though the very next thing we do is to emit an update signal. which removes it.*/
m_fileList.setAutoDelete(false);
m_fileList.removeRef(file);
emit avFileListUpdated();
delete file;
m_fileList.setAutoDelete(true);
} else {
kdError() << "Trying to delete AVFile that is not in document!" << endl;
}
......@@ -619,3 +603,16 @@ void KdenliveDoc::indirectlyModified()
{
hasBeenModified();
}
QPtrList<DocClipBase> KdenliveDoc::referencedClips(AVFile *file)
{
QPtrList<DocClipBase> list;
if(m_projectClip) {
list = m_projectClip->referencedClips(file);
} else {
kdError() << "Cannot get referenced clips - m_projectClip is null!" << endl;
}
return list;
}
......@@ -90,10 +90,7 @@ class KdenliveDoc : public QObject
/** sets the URL of the document */
void setURL(const KURL& url);
/** Returns the internal avFile list. */
const AVFileList &avFileList();
/** Insert an AVFile with the given url. If the file is already in the file list, return
* that instead. */
AVFile *insertAVFile(const KURL &file);
const AVFileList &avFileList() const;
/** Itterates through the tracks in the project. This works in the same way
* as QPtrList::next(), although the underlying structures may be different. */
DocTrackBase * nextTrack();
......@@ -101,11 +98,9 @@ class KdenliveDoc : public QObject
*This effectively is the same as QPtrList::first(), but the underyling implementation
* may change. */
DocTrackBase * firstTrack();
/** HACK - in some cases, we can modify the document without it knowing - we tell it here
* for the moment, although really, this means we have access to things that either we should
* only modify via an interface to the document, or that the things that we are modifying should
* automatically tell the document. */
void indirectlyModified();
/** Returns a list of all clips directly or indirectly accessed by the specified avfile. */
QPtrList<DocClipBase> referencedClips(AVFile *file);
public slots:
/** calls repaint() on all views connected to the document object and is called by the view
* by which the document has been changed. As this view normally repaints itself, it is
......@@ -118,26 +113,26 @@ public slots:
void addSoundTrack();
/** Adds an empty video track to the project */
void addVideoTrack();
/** Inserts a list of clips into the document, updating the project accordingly. */
void slot_insertClips(QPtrList<DocClipBase> clips);
/** Given a drop event, inserts all contained clips into the project list, if they are not
* there already.
*/
void slot_insertClips(QDropEvent *event);
/** This slot occurs when the File properties for an AV File have been returned by the renderer.
The relevant AVFile can then be updated to the correct status. */
void AVFilePropertiesArrived(QMap<QString, QString> properties);
/** Called when an error occurs whilst retrieving a file's properties. */
void AVFilePropertiesError(const QString &path, const QString &errmsg);
protected slots:
/** Inserts a list of clips into the document, updating the project accordingly. */
void slot_insertClips(QPtrList<DocClipBase> clips);
/** Given a drop event, inserts all contained clips into the project list, if they are not
* there already. */
void slot_insertClips(QDropEvent *event);
public:
/** Returns the number of frames per second. */
int framesPerSecond() const;
uint numTracks();
/** Returns a reference to the AVFile matching the url. If no AVFile matching the given url
* is found, then one will be created. Either way, the reference count for the AVFile will
* be incremented by one, and the file will be returned.
*/
/** Returns a reference to the AVFile matching the url. If no AVFile matching the given url is
found, then one will be created. This method is not in charge of incrementing the reference count
of the avfile - this must be done by the calling function. */
AVFile * getAVFileReference(KURL url);
/** Find and return the AVFile with the url specified, or return null is no file matches. */
AVFile * findAVFile(const KURL &file);
......@@ -152,15 +147,6 @@ public:
QDomDocument toXML();
/** Sets the modified state of the document, if this has changed, emits modified(state) */
void setModified(bool state);
/** Removes entries from the AVFileList which are unreferenced by any clips. */
void cleanAVFileList();
/** Finds and removes the specified avfile from the document. If there are any
clips on the timeline which use this clip, then they will be deleted as well.
Emits AVFileList changed if successful. */
void deleteAVFile(AVFile *file);
/** Moves the currectly selected clips by the offsets specified, or returns false if this
is not possible. */
bool moveSelectedClips(GenTime startOffset, int trackOffset);
/** Returns a scene list generated from the current document. */
QDomDocument generateSceneList();
/** Renders the current document timeline to the specified url. */
......@@ -172,7 +158,22 @@ public:
/** returns the duration of the project. */
GenTime projectDuration() const;
// protected:
/** Insert an AVFile with the given url. If the file is already in the file list, return
* that instead. */
AVFile *insertAVFile(const KURL &file);
/** HACK - in some cases, we can modify the document without it knowing - we tell it here
* for the moment, although really, this means we have access to things that either we should
* only modify via an interface to the document, or that the things that we are modifying should
* automatically tell the document. */
void indirectlyModified();
/** Moves the currectly selected clips by the offsets specified, or returns false if this
is not possible. */
bool moveSelectedClips(GenTime startOffset, int trackOffset);
/** Finds and removes the specified avfile from the document. If there are any
clips on the timeline which use this clip, then they will be deleted as well.
Emits AVFileList changed if successful. */
void deleteAVFile(AVFile *file);
private:
/** The base clip for this document. This must be a project clip, as it lists the tracks within
* the project, etc. */
......
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