1 /*
2 SPDX-FileCopyrightText: 2012 Till Theato <root@ttill.de>
3 SPDX-FileCopyrightText: 2014 Jean-Baptiste Mardelle <jb@kdenlive.org>
4 This file is part of Kdenlive. See www.kdenlive.org.
5 
6 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
7 */
8 
9 #include "projectfolder.h"
10 #include "bin.h"
11 #include "core.h"
12 #include "projectclip.h"
13 #include "projectitemmodel.h"
14 
15 #include <KLocalizedString>
16 #include <QDomElement>
17 #include <utility>
ProjectFolder(const QString & id,const QString & name,const std::shared_ptr<ProjectItemModel> & model)18 ProjectFolder::ProjectFolder(const QString &id, const QString &name, const std::shared_ptr<ProjectItemModel> &model)
19     : AbstractProjectItem(AbstractProjectItem::FolderItem, id, model)
20 {
21     m_name = name;
22     m_clipStatus = FileStatus::StatusReady;
23     m_thumbnail = QIcon::fromTheme(QStringLiteral("folder"));
24 }
25 
construct(const QString & id,const QString & name,std::shared_ptr<ProjectItemModel> model)26 std::shared_ptr<ProjectFolder> ProjectFolder::construct(const QString &id, const QString &name, std::shared_ptr<ProjectItemModel> model)
27 {
28     std::shared_ptr<ProjectFolder> self(new ProjectFolder(id, name, std::move(model)));
29 
30     baseFinishConstruct(self);
31     return self;
32 }
33 
ProjectFolder(const std::shared_ptr<ProjectItemModel> & model)34 ProjectFolder::ProjectFolder(const std::shared_ptr<ProjectItemModel> &model)
35     : AbstractProjectItem(AbstractProjectItem::FolderItem, QString::number(-1), model, true)
36 {
37     m_name = QStringLiteral("root");
38 }
39 
construct(std::shared_ptr<ProjectItemModel> model)40 std::shared_ptr<ProjectFolder> ProjectFolder::construct(std::shared_ptr<ProjectItemModel> model)
41 {
42     std::shared_ptr<ProjectFolder> self(new ProjectFolder(std::move(model)));
43 
44     baseFinishConstruct(self);
45     return self;
46 }
47 
48 ProjectFolder::~ProjectFolder() = default;
49 
clip(const QString & id)50 std::shared_ptr<ProjectClip> ProjectFolder::clip(const QString &id)
51 {
52     for (int i = 0; i < childCount(); ++i) {
53         std::shared_ptr<ProjectClip> clip = std::static_pointer_cast<ProjectClip>(child(i))->clip(id);
54         if (clip) {
55             return clip;
56         }
57     }
58     return std::shared_ptr<ProjectClip>();
59 }
60 
childClips()61 QList<std::shared_ptr<ProjectClip>> ProjectFolder::childClips()
62 {
63     QList<std::shared_ptr<ProjectClip>> allChildren;
64     for (int i = 0; i < childCount(); ++i) {
65         std::shared_ptr<AbstractProjectItem> childItem = std::static_pointer_cast<AbstractProjectItem>(child(i));
66         if (childItem->itemType() == ClipItem) {
67             allChildren << std::static_pointer_cast<ProjectClip>(childItem);
68         } else if (childItem->itemType() == FolderItem) {
69             allChildren << std::static_pointer_cast<ProjectFolder>(childItem)->childClips();
70         }
71     }
72     return allChildren;
73 }
74 
childByHash(const QString & hash)75 QString ProjectFolder::childByHash(const QString &hash)
76 {
77     QList<std::shared_ptr<ProjectClip>> allChildren;
78     for (int i = 0; i < childCount(); ++i) {
79         std::shared_ptr<AbstractProjectItem> childItem = std::static_pointer_cast<AbstractProjectItem>(child(i));
80         if (childItem->itemType() == ClipItem) {
81             allChildren << std::static_pointer_cast<ProjectClip>(childItem);
82         } else if (childItem->itemType() == FolderItem) {
83             allChildren << std::static_pointer_cast<ProjectFolder>(childItem)->childClips();
84         }
85     }
86     for (auto &clip : allChildren) {
87         if (clip->statusReady() && clip->hash() == hash) {
88             return clip->clipId();
89         }
90     }
91     return QString();
92 }
93 
hasChildClips() const94 bool ProjectFolder::hasChildClips() const
95 {
96     for (int i = 0; i < childCount(); ++i) {
97         std::shared_ptr<AbstractProjectItem> childItem = std::static_pointer_cast<AbstractProjectItem>(child(i));
98         if (childItem->itemType() == ClipItem) {
99             return true;
100         }
101         if (childItem->itemType() == FolderItem) {
102             bool hasChildren = std::static_pointer_cast<ProjectFolder>(childItem)->hasChildClips();
103             if (hasChildren) {
104                 return true;
105             }
106         }
107     }
108     return false;
109 }
110 
getToolTip() const111 QString ProjectFolder::getToolTip() const
112 {
113     return i18np("%1 clip", "%1 clips", childCount());
114 }
115 
folder(const QString & id)116 std::shared_ptr<ProjectFolder> ProjectFolder::folder(const QString &id)
117 {
118     if (m_binId == id) {
119         return std::static_pointer_cast<ProjectFolder>(shared_from_this());
120     }
121     for (int i = 0; i < childCount(); ++i) {
122         std::shared_ptr<ProjectFolder> folderItem = std::static_pointer_cast<ProjectFolder>(child(i))->folder(id);
123         if (folderItem) {
124             return folderItem;
125         }
126     }
127     return std::shared_ptr<ProjectFolder>();
128 }
129 
clipAt(int index)130 std::shared_ptr<ProjectClip> ProjectFolder::clipAt(int index)
131 {
132     if (childCount() == 0) {
133         return std::shared_ptr<ProjectClip>();
134     }
135     for (int i = 0; i < childCount(); ++i) {
136         std::shared_ptr<ProjectClip> clip = std::static_pointer_cast<AbstractProjectItem>(child(i))->clipAt(index);
137         if (clip) {
138             return clip;
139         }
140     }
141     return std::shared_ptr<ProjectClip>();
142 }
143 
setBinEffectsEnabled(bool enabled)144 void ProjectFolder::setBinEffectsEnabled(bool enabled)
145 {
146     for (int i = 0; i < childCount(); ++i) {
147         std::shared_ptr<AbstractProjectItem> item = std::static_pointer_cast<AbstractProjectItem>(child(i));
148         item->setBinEffectsEnabled(enabled);
149     }
150 }
151 
toXml(QDomDocument & document,bool,bool)152 QDomElement ProjectFolder::toXml(QDomDocument &document, bool, bool)
153 {
154     QDomElement folder = document.createElement(QStringLiteral("folder"));
155     folder.setAttribute(QStringLiteral("name"), name());
156     for (int i = 0; i < childCount(); ++i) {
157         folder.appendChild(std::static_pointer_cast<AbstractProjectItem>(child(i))->toXml(document));
158     }
159     return folder;
160 }
161 
rename(const QString & name,int column)162 bool ProjectFolder::rename(const QString &name, int column)
163 {
164     Q_UNUSED(column)
165     if (m_name == name) {
166         return false;
167     }
168     // Rename folder
169     if (auto ptr = m_model.lock()) {
170         auto self = std::static_pointer_cast<ProjectFolder>(shared_from_this());
171         return std::static_pointer_cast<ProjectItemModel>(ptr)->requestRenameFolder(self, name);
172     }
173     qDebug() << "ERROR: Impossible to rename folder because model is not available";
174     Q_ASSERT(false);
175     return false;
176 }
177 
clipType() const178 ClipType::ProducerType ProjectFolder::clipType() const
179 {
180     return ClipType::Unknown;
181 }
182 
hasAudioAndVideo() const183 bool ProjectFolder::hasAudioAndVideo() const
184 {
185     return false;
186 }
187