Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 8c78de06 authored by Nicolas Carion's avatar Nicolas Carion

Reimplement cleanup function and clean a lot of clutter in the old code

parent 35922815
......@@ -1013,6 +1013,9 @@ void Bin::slotDeleteClip()
std::vector<std::shared_ptr<AbstractProjectItem>> items;
bool included = false;
bool usedFolder = false;
auto checkInclusion = [](bool accum, std::shared_ptr<TreeItem> item) {
return accum || std::static_pointer_cast<AbstractProjectItem>(item)->isIncludedInTimeline();
};
for (const QModelIndex &ix : indexes) {
if (!ix.isValid() || ix.column() != 0) {
continue;
......@@ -1022,9 +1025,6 @@ void Bin::slotDeleteClip()
qDebug() << "Suspicious: item not found when trying to delete";
continue;
}
auto checkInclusion = [](bool included, std::shared_ptr<TreeItem> item) {
return included || std::static_pointer_cast<AbstractProjectItem>(item)->isIncludedInTimeline();
};
included = included || item->accumulate(false, checkInclusion);
// Check if we are deleting non-empty folders:
usedFolder = usedFolder || item->childCount() > 0;
......@@ -1042,107 +1042,6 @@ void Bin::slotDeleteClip()
m_itemModel->requestBinClipDeletion(item, undo, redo);
}
pCore->pushUndo(undo, redo, i18n("Delete bin Clips"));
/*
QStringList clipIds;
QStringList subClipIds;
QStringList foldersIds;
std::shared_ptr<ProjectSubClip> sub;
QPoint zone;
bool usedFolder = false;
// check folders, remove child folders if there is any
QList<std::shared_ptr<ProjectFolder>> topFolders;
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
for (const QModelIndex &ix : indexes) {
if (!ix.isValid() || ix.column() != 0) {
continue;
}
std::shared_ptr<AbstractProjectItem> item = m_itemModel->getBinItemByIndex(m_proxyModel->mapToSource(ix));
if (!item) {
continue;
}
if (item->itemType() == AbstractProjectItem::SubClipItem) {
QString subId = item->clipId();
sub = std::static_pointer_cast<ProjectSubClip>(item);
zone = sub->zone();
subId.append(QLatin1Char(':') + QString::number(zone.x()) + QLatin1Char(':') + QString::number(zone.y()));
subClipIds << subId;
continue;
}
if (item->itemType() != AbstractProjectItem::FolderItem) {
continue;
}
auto current = std::static_pointer_cast<ProjectFolder>(item);
if (!usedFolder && current->childCount() != 0) {
usedFolder = true;
}
if (topFolders.isEmpty()) {
topFolders << current;
continue;
}
// parse all folders to check for children
bool isChild = false;
for (std::shared_ptr<ProjectFolder> f : topFolders) {
if (f->folder(current->clipId())) {
// Current is a child, no need to take it into account
isChild = true;
break;
}
}
if (isChild) {
continue;
}
QList<std::shared_ptr<ProjectFolder>> childFolders;
// parse all folders to check for children
for (std::shared_ptr<ProjectFolder> f : topFolders) {
if (current->folder(f->clipId())) {
childFolders << f;
}
}
if (!childFolders.isEmpty()) {
// children are in the list, remove from
for (std::shared_ptr<ProjectFolder> f : childFolders) {
topFolders.removeAll(f);
}
}
topFolders << current;
}
for (std::shared_ptr<ProjectFolder> f : topFolders) {
foldersIds << f->clipId();
}
bool usedClips = false;
QList<std::shared_ptr<ProjectFolder>> topClips;
// Check if clips are in already selected folders
for (const QModelIndex &ix : indexes) {
if (!ix.isValid() || ix.column() != 0) {
continue;
}
std::shared_ptr<AbstractProjectItem> item = m_itemModel->getBinItemByIndex(m_proxyModel->mapToSource(ix));
if ((item == nullptr) || item->itemType() != AbstractProjectItem::ClipItem) {
continue;
}
auto current = std::static_pointer_cast<ProjectClip>(item);
bool isChild = false;
for (std::shared_ptr<ProjectFolder> f : topFolders) {
if (current->hasParent(f->clipId())) {
isChild = true;
break;
}
}
if (!isChild) {
if (!usedClips && current->refCount() > 0) {
usedClips = true;
}
clipIds << current->AbstractProjectItem::clipId();
}
}
if (usedClips && (KMessageBox::warningContinueCancel(this, i18n("This will delete all selected clips from timeline")) != KMessageBox::Continue)) {
return;
}
if (usedFolder && (KMessageBox::warningContinueCancel(this, i18n("This will delete all folder content")) != KMessageBox::Continue)) {
return;
}
m_doc->clipManager()->deleteProjectItems(clipIds, foldersIds, subClipIds);
*/
}
void Bin::slotReloadClip()
......@@ -1466,17 +1365,6 @@ void Bin::selectClipById(const QString &clipId, int frame, const QPoint &zone)
}
}
void Bin::doAddFolder(const QString &id, const QString &name, const QString &parentId)
{
std::shared_ptr<ProjectFolder> parentFolder = m_itemModel->getFolderByBinId(parentId);
if (!parentFolder) {
qCDebug(KDENLIVE_LOG) << " / / ERROR IN PARENT FOLDER";
return;
}
std::shared_ptr<ProjectFolder> new_folder = ProjectFolder::construct(id, name, m_itemModel);
parentFolder->appendChild(new_folder);
emit storeFolder(id, parentId, QString(), name);
}
void Bin::slotLoadFolders(const QMap<QString, QString> &foldersData)
{
......@@ -1532,41 +1420,6 @@ void Bin::slotLoadFolders(const QMap<QString, QString> &foldersData)
}
}
void Bin::removeFolder(const QString &id, QUndoCommand *deleteCommand)
{
// Check parent item
std::shared_ptr<ProjectFolder> folder = m_itemModel->getFolderByBinId(id);
if ((folder == nullptr) || (folder->parent() == nullptr)) {
qCDebug(KDENLIVE_LOG) << " / / ERROR when removing folder: folder is invalid or is root";
return;
}
std::shared_ptr<AbstractProjectItem> parent = folder->parent();
if (folder->childCount() != 0) {
// Folder has clips inside, warn user
if (KMessageBox::warningContinueCancel(this, i18np("Folder contains a clip, delete anyways ?", "Folder contains %1 clips, delete anyways ?",
folder->childCount())) != KMessageBox::Continue) {
return;
}
QStringList clipIds;
QStringList folderIds;
// TODO: manage subclips
for (int i = 0; i < folder->childCount(); i++) {
std::shared_ptr<AbstractProjectItem> child = std::static_pointer_cast<AbstractProjectItem>(folder->child(i));
switch (child->itemType()) {
case AbstractProjectItem::ClipItem:
clipIds << child->clipId();
break;
case AbstractProjectItem::FolderItem:
folderIds << child->clipId();
break;
default:
break;
}
}
m_doc->clipManager()->deleteProjectItems(clipIds, folderIds, QStringList(), deleteCommand);
}
new AddBinFolderCommand(this, folder->clipId(), folder->name(), parent->clipId(), true, deleteCommand);
}
void Bin::removeSubClip(const QString &id, QUndoCommand *deleteCommand)
{
......@@ -1578,18 +1431,6 @@ void Bin::removeSubClip(const QString &id, QUndoCommand *deleteCommand)
new AddBinClipCutCommand(this, clipId, in, out, false, deleteCommand);
}
void Bin::doRemoveFolder(const QString &id)
{
std::shared_ptr<ProjectFolder> folder = m_itemModel->getFolderByBinId(id);
if (!folder) {
qCDebug(KDENLIVE_LOG) << " / / FOLDER not found";
return;
}
// TODO: warn user on non-empty folders
std::shared_ptr<AbstractProjectItem> parent = folder->parent();
parent->removeChild(folder);
emit storeFolder(id, parent->clipId(), QString(), QString());
}
void Bin::selectProxyModel(const QModelIndex &id)
{
......@@ -2715,6 +2556,8 @@ void Bin::slotItemDropped(const QList<QUrl> &urls, const QModelIndex &parent)
void Bin::slotExpandUrl(const ItemInfo &info, const QString &url, QUndoCommand *command)
{
//TODO reimplement this
/*
// Create folder to hold imported clips
QString folderName = QFileInfo(url).fileName().section(QLatin1Char('.'), 0, 0);
QString folderId = QString::number(getFreeFolderId());
......@@ -2830,6 +2673,7 @@ void Bin::slotExpandUrl(const ItemInfo &info, const QString &url, QUndoCommand *
ClipCreationDialog::createClipsCommand(this, clone, newId, command);
}
pCore->projectManager()->currentTimeline()->importPlaylist(info, idMap, doc, command);
*/
}
void Bin::slotItemEdited(const QModelIndex &ix, const QModelIndex &, const QVector<int> &)
......@@ -3578,21 +3422,6 @@ void Bin::resetUsageCount()
}
}
void Bin::cleanup()
{
QList<std::shared_ptr<ProjectClip>> clipList = m_itemModel->getRootFolder()->childClips();
QStringList ids;
QStringList subIds;
for (std::shared_ptr<ProjectClip> clip : clipList) {
if (clip->refCount() == 0) {
ids << clip->AbstractProjectItem::clipId();
subIds << clip->subClipIds();
}
}
auto *command = new QUndoCommand();
command->setText(i18n("Clean Project"));
m_doc->clipManager()->doDeleteClips(ids, QStringList(), subIds, command, true);
}
void Bin::getBinStats(uint *used, uint *unused, qint64 *usedSize, qint64 *unusedSize)
{
......@@ -3706,3 +3535,8 @@ void Bin::setCurrent(std::shared_ptr<AbstractProjectItem> item)
break;
}
}
void Bin::cleanup()
{
m_itemModel->requestCleanup();
}
......@@ -243,11 +243,8 @@ public:
/** @brief Ask MLT to reload this clip's producer */
void reloadClip(const QString &id);
/** @brief Delete a folder */
void doRemoveFolder(const QString &id);
/** @brief Add a folder */
void doAddFolder(const QString &id, const QString &name, const QString &parentId);
void removeFolder(const QString &id, QUndoCommand *deleteCommand);
void removeSubClip(const QString &id, QUndoCommand *deleteCommand);
void doMoveClip(const QString &id, const QString &newParentId);
void doMoveFolder(const QString &id, const QString &newParentId);
......@@ -299,8 +296,6 @@ public:
bool isEmpty() const;
/** @brief Trigger reload of all clips. */
void reloadAllProducers();
/** @brief Remove all unused clip from project bin. */
void cleanup();
/** @brief Get usage stats for project bin. */
void getBinStats(uint *used, uint *unused, qint64 *usedSize, qint64 *unusedSize);
/** @brief Returns the clip properties dockwidget. */
......@@ -321,6 +316,8 @@ public:
void saveZone(const QStringList &info, const QDir &dir);
QVariantList audioFrameCache(const QString &id);
// TODO refac: remove this and call directly the function in ProjectItemModel
void cleanup();
private slots:
void slotAddClip();
void slotReloadClip();
......
......@@ -23,39 +23,6 @@
#include <klocalizedstring.h>
AddBinFolderCommand::AddBinFolderCommand(Bin *bin, const QString &id, const QString &name, const QString &parentId, bool remove, QUndoCommand *parent)
: QUndoCommand(parent)
, m_bin(bin)
, m_id(id)
, m_name(name)
, m_parentId(parentId)
, m_remove(remove)
{
if (remove) {
setText(i18n("Remove Folder"));
} else {
setText(i18n("Add Folder"));
}
}
// virtual
void AddBinFolderCommand::undo()
{
if (m_remove) {
m_bin->doAddFolder(m_id, m_name, m_parentId);
} else {
m_bin->doRemoveFolder(m_id);
}
}
// virtual
void AddBinFolderCommand::redo()
{
if (m_remove) {
m_bin->doRemoveFolder(m_id);
} else {
m_bin->doAddFolder(m_id, m_name, m_parentId);
}
}
MoveBinClipCommand::MoveBinClipCommand(Bin *bin, const QString &clipId, const QString &oldParentId, const QString &newParentId, QUndoCommand *parent)
: QUndoCommand(parent)
, m_bin(bin)
......
......@@ -26,21 +26,6 @@
class Bin;
class AddBinFolderCommand : public QUndoCommand
{
public:
explicit AddBinFolderCommand(Bin *bin, const QString &id, const QString &name, const QString &parentId, bool remove = false,
QUndoCommand *parent = nullptr);
void undo() override;
void redo() override;
private:
Bin *m_bin;
QString m_id;
QString m_name;
QString m_parentId;
bool m_remove;
};
class MoveBinClipCommand : public QUndoCommand
{
......
......@@ -554,3 +554,29 @@ Fun ProjectItemModel::removeBin_lambda(int binId)
return true;
};
}
bool ProjectItemModel::requestCleanup()
{
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool res = true;
std::vector<std::shared_ptr<AbstractProjectItem>> to_delete;
for (const auto &clip : m_allItems) {
auto c = std::static_pointer_cast<AbstractProjectItem>(clip.second.lock());
if (c->itemType() == AbstractProjectItem::ClipItem && !c->isIncludedInTimeline()) {
to_delete.push_back(c);
}
}
// it is important to execute deletion in a separate loop, because otherwise
// the iterators of m_allItems get messed up
for (const auto &c : to_delete) {
res = requestBinClipDeletion(c, undo, redo);
if (!res) {
bool undone = undo();
Q_ASSERT(undone);
return false;
}
}
pCore->pushUndo(undo, redo, i18n("Clean Project"));
return true;
}
......@@ -126,12 +126,15 @@ public:
/* Same functions but pushes the undo object directly */
bool requestRenameFolder(std::shared_ptr<AbstractProjectItem> folder, const QString &name);
/* @brief Request that the unused clips are deleted */
bool requestCleanup();
protected:
/* @brief Register the existence of a new element
*/
void registerItem(const std::shared_ptr<TreeItem> &item) override;
void deregisterItem(int id, TreeItem *item) override;
protected:
/* @brief This function updates the underlying binPlaylist object to reflect deletion of a bin item
@param binElem is the bin item deleted. Note that exceptionnally, this function takes a raw pointer instead of a smart one.
This is because the function will be called in the middle of the element's destructor, so no smart pointer is available at that time.
......
......@@ -189,58 +189,6 @@ void ClipManager::slotGetThumbs()
emit displayMessage(QString(), -1);
}
void ClipManager::deleteProjectItems(const QStringList &clipIds, const QStringList &folderIds, const QStringList &subClipIds, QUndoCommand *deleteCommand)
{
// Create meta command
bool execute = deleteCommand == nullptr;
if (execute) {
deleteCommand = new QUndoCommand();
}
if (clipIds.isEmpty()) {
// Deleting folder only
if (!subClipIds.isEmpty()) {
deleteCommand->setText(i18np("Delete subclip", "Delete subclips", subClipIds.count()));
} else {
deleteCommand->setText(i18np("Delete folder", "Delete folders", folderIds.count()));
}
} else {
deleteCommand->setText(i18np("Delete clip", "Delete clips", clipIds.count()));
}
// TODO REFAC: delete clips from timeline
if (pCore->projectManager()->currentTimeline()) {
// Remove clips from timeline
if (!clipIds.isEmpty()) {
for (int i = 0; i < clipIds.size(); ++i) {
pCore->projectManager()->currentTimeline()->slotDeleteClip(clipIds.at(i), deleteCommand);
}
}
}
// remove clips and folders from bin
doDeleteClips(clipIds, folderIds, subClipIds, deleteCommand, execute);
}
void ClipManager::doDeleteClips(const QStringList &clipIds, const QStringList &folderIds, const QStringList &subClipIds, QUndoCommand *deleteCommand,
bool execute)
{
for (int i = 0; i < clipIds.size(); ++i) {
QString xml = pCore->binController()->xmlFromId(clipIds.at(i));
if (!xml.isEmpty()) {
QDomDocument doc;
doc.setContent(xml);
new AddClipCommand(pCore->bin(), doc.documentElement(), clipIds.at(i), false, deleteCommand);
}
}
for (int i = 0; i < folderIds.size(); ++i) {
pCore->bin()->removeFolder(folderIds.at(i), deleteCommand);
}
for (int i = 0; i < subClipIds.size(); ++i) {
pCore->bin()->removeSubClip(subClipIds.at(i), deleteCommand);
}
if (execute) {
m_doc->commandStack()->push(deleteCommand);
}
}
void ClipManager::slotAddCopiedClip(KIO::Job *, const QUrl &, const QUrl &dst)
{
......
......@@ -65,10 +65,8 @@ class ClipManager : public QObject
virtual ~ClipManager();
void slotAddTextTemplateClip(const QString &titleName, const QUrl &path, const QString &group, const QString &groupId);
void doDeleteClips(const QStringList &clipIds, const QStringList &folderIds, const QStringList &subClipIds, QUndoCommand *deleteCommand, bool execute);
int lastClipId() const;
/** @brief Prepare deletion of clips and folders from the Bin. */
void deleteProjectItems(const QStringList &clipIds, const QStringList &folderIds, const QStringList &subClipIds, QUndoCommand *deleteCommand = nullptr);
void clear();
void clearCache();
AbstractGroupItem *createGroup();
......
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