]> git.sesse.net Git - kdenlive/blob - src/projectsettings.cpp
Cleanup physical clip deletion:
[kdenlive] / src / projectsettings.cpp
1 /***************************************************************************
2  *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20 #include "projectsettings.h"
21 #include "kdenlivesettings.h"
22 #include "profilesdialog.h"
23 #include "docclipbase.h"
24
25 #include <KStandardDirs>
26 #include <KMessageBox>
27 #include <KDebug>
28 #include <kio/directorysizejob.h>
29 #include <KIO/NetAccess>
30
31 #include <QDir>
32 #include <kmessagebox.h>
33
34 ProjectSettings::ProjectSettings(ProjectList *projectlist, int videotracks, int audiotracks, const QString projectPath, bool readOnlyTracks, bool savedProject, QWidget * parent) :
35         QDialog(parent), m_savedProject(savedProject), m_projectList(projectlist)
36 {
37     setupUi(this);
38
39     QMap <QString, QString> profilesInfo = ProfilesDialog::getProfilesInfo();
40     QMapIterator<QString, QString> i(profilesInfo);
41     while (i.hasNext()) {
42         i.next();
43         profiles_list->addItem(i.key(), i.value());
44     }
45     project_folder->setMode(KFile::Directory);
46     project_folder->setUrl(KUrl(projectPath));
47     QString currentProf = KdenliveSettings::current_profile();
48
49     for (int i = 0; i < profiles_list->count(); i++) {
50         if (profiles_list->itemData(i).toString() == currentProf) {
51             profiles_list->setCurrentIndex(i);
52             break;
53         }
54     }
55
56     m_buttonOk = buttonBox->button(QDialogButtonBox::Ok);
57     //buttonOk->setEnabled(false);
58     audio_thumbs->setChecked(KdenliveSettings::audiothumbnails());
59     video_thumbs->setChecked(KdenliveSettings::videothumbnails());
60     audio_tracks->setValue(audiotracks);
61     video_tracks->setValue(videotracks);
62     if (readOnlyTracks) {
63         video_tracks->setEnabled(false);
64         audio_tracks->setEnabled(false);
65     }
66     slotUpdateDisplay();
67     if (m_projectList != NULL) {
68         slotUpdateFiles();
69         connect(clear_cache, SIGNAL(clicked()), this, SLOT(slotClearCache()));
70         connect(delete_unused, SIGNAL(clicked()), this, SLOT(slotDeleteUnused()));
71     } else tabWidget->widget(1)->setEnabled(false);
72     connect(profiles_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDisplay()));
73     connect(project_folder, SIGNAL(textChanged(const QString &)), this, SLOT(slotUpdateButton(const QString &)));
74 }
75
76 void ProjectSettings::slotDeleteUnused()
77 {
78     QStringList toDelete;
79     QList <DocClipBase*> list = m_projectList->documentClipList();
80     for (int i = 0; i < list.count(); i++) {
81         DocClipBase *clip = list.at(i);
82         if (clip->numReferences() == 0) {
83             KUrl url = clip->fileURL();
84             if (!url.isEmpty()) toDelete << url.path();
85         }
86     }
87     toDelete.removeDuplicates();
88
89     // make sure our urls are not used in another clip
90     for (int i = 0; i < list.count(); i++) {
91         DocClipBase *clip = list.at(i);
92         if (clip->numReferences() > 0) {
93             KUrl url = clip->fileURL();
94             if (!url.isEmpty() && toDelete.contains(url.path())) toDelete.removeAll(url.path());
95         }
96     }
97
98     if (toDelete.count() == 0) {
99         // No physical url to delete, we only remove unused clips from project (color clips for example have no physical url)
100         if (KMessageBox::warningContinueCancel(this, i18n("This will remove all unused clips from your project."), i18n("Clean up project")) == KMessageBox::Cancel) return;
101         m_projectList->cleanup();
102         slotUpdateFiles();
103         return;
104     }
105     if (KMessageBox::warningYesNoList(this, i18n("This will remove the following files from your hard drive.\nThis action cannot be undone, only use if you know what you are doing.\nAre you sure you want to continue?"), toDelete, i18n("Delete unused clips")) != KMessageBox::Yes) return;
106     m_projectList->trashUnusedClips();
107     slotUpdateFiles();
108 }
109
110 void ProjectSettings::slotClearCache()
111 {
112     buttonBox->setEnabled(false);
113     KIO::NetAccess::del(KUrl(project_folder->url().path(KUrl::AddTrailingSlash) + "thumbs/"), this);
114     KStandardDirs::makeDir(project_folder->url().path(KUrl::AddTrailingSlash) + "thumbs/");
115     buttonBox->setEnabled(true);
116     slotUpdateFiles(true);
117 }
118
119 void ProjectSettings::slotUpdateFiles(bool cacheOnly)
120 {
121     KIO::DirectorySizeJob * job = KIO::directorySize(project_folder->url().path(KUrl::AddTrailingSlash) + "thumbs/");
122     job->exec();
123     thumbs_count->setText(QString::number(job->totalFiles()));
124     thumbs_size->setText(KIO::convertSize(job->totalSize()));
125     delete job;
126     if (cacheOnly) return;
127     int unused = 0;
128     int used = 0;
129     KIO::filesize_t usedSize = 0;
130     KIO::filesize_t unUsedSize = 0;
131     QList <DocClipBase*> list = m_projectList->documentClipList();
132
133     for (int i = 0; i < list.count(); i++) {
134         DocClipBase *clip = list.at(i);
135         if (clip->numReferences() == 0) {
136             unused++;
137             unUsedSize += clip->fileSize();
138         } else {
139             used++;
140             usedSize += clip->fileSize();
141         }
142     }
143     used_count->setText(QString::number(used));
144     used_size->setText(KIO::convertSize(usedSize));
145     unused_count->setText(QString::number(unused));
146     unused_size->setText(KIO::convertSize(unUsedSize));
147     delete_unused->setEnabled(unused > 0);
148 }
149
150 void ProjectSettings::accept()
151 {
152     if (!m_savedProject && selectedProfile() != KdenliveSettings::current_profile())
153         if (KMessageBox::warningContinueCancel(this, i18n("Changing the profile of your project cannot be undone.\nIt is recommended to save your project before attempting this operation that might cause some corruption in transitions.\n Are you sure you want to proceed?"), i18n("Confirm profile change")) == KMessageBox::Cancel) return;
154     QDialog::accept();
155 }
156
157 void ProjectSettings::slotUpdateDisplay()
158 {
159     QString currentProfile = profiles_list->itemData(profiles_list->currentIndex()).toString();
160     QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(currentProfile);
161     p_size->setText(values.value("width") + 'x' + values.value("height"));
162     p_fps->setText(values.value("frame_rate_num") + '/' + values.value("frame_rate_den"));
163     p_aspect->setText(values.value("sample_aspect_num") + '/' + values.value("sample_aspect_den"));
164     p_display->setText(values.value("display_aspect_num") + '/' + values.value("display_aspect_den"));
165     if (values.value("progressive").toInt() == 0) p_progressive->setText(i18n("Interlaced"));
166     else p_progressive->setText(i18n("Progressive"));
167 }
168
169 void ProjectSettings::slotUpdateButton(const QString &path)
170 {
171     if (path.isEmpty()) m_buttonOk->setEnabled(false);
172     else {
173         m_buttonOk->setEnabled(true);
174         slotUpdateFiles(true);
175     }
176 }
177
178 QString ProjectSettings::selectedProfile() const
179 {
180     return profiles_list->itemData(profiles_list->currentIndex()).toString();
181 }
182
183 KUrl ProjectSettings::selectedFolder() const
184 {
185     return project_folder->url();
186 }
187
188 QPoint ProjectSettings::tracks()
189 {
190     QPoint p;
191     p.setX(video_tracks->value());
192     p.setY(audio_tracks->value());
193     return p;
194 }
195
196 bool ProjectSettings::enableVideoThumbs() const
197 {
198     return video_thumbs->isChecked();
199 }
200
201 bool ProjectSettings::enableAudioThumbs() const
202 {
203     return audio_thumbs->isChecked();
204 }
205
206 #include "projectsettings.moc"
207
208