Changeset View
Changeset View
Standalone View
Standalone View
importer/importer.cpp
Show All 27 Lines | |||||
28 | #include <QTemporaryDir> | 28 | #include <QTemporaryDir> | ||
29 | 29 | | |||
30 | // KDE | 30 | // KDE | ||
31 | #include <KFileItem> | 31 | #include <KFileItem> | ||
32 | #include <KIO/CopyJob> | 32 | #include <KIO/CopyJob> | ||
33 | #include <KIO/DeleteJob> | 33 | #include <KIO/DeleteJob> | ||
34 | #include <KIO/MkpathJob> | 34 | #include <KIO/MkpathJob> | ||
35 | #include <KIO/Job> | 35 | #include <KIO/Job> | ||
36 | #include <kio/jobclasses.h> | ||||
36 | #include <KIO/JobUiDelegate> | 37 | #include <KIO/JobUiDelegate> | ||
37 | #include <KJobWidgets> | 38 | #include <KJobWidgets> | ||
38 | #include <KLocalizedString> | 39 | #include <KLocalizedString> | ||
39 | 40 | | |||
40 | // stdc++ | 41 | // stdc++ | ||
41 | #include <memory> | 42 | #include <memory> | ||
42 | 43 | | |||
43 | // Local | 44 | // Local | ||
44 | #include <fileutils.h> | 45 | #include <fileutils.h> | ||
45 | #include <filenameformater.h> | 46 | #include <filenameformater.h> | ||
46 | #include <lib/timeutils.h> | 47 | #include <lib/timeutils.h> | ||
48 | #include <lib/urlutils.h> | ||||
47 | #include <QDir> | 49 | #include <QDir> | ||
48 | 50 | | |||
49 | namespace Gwenview | 51 | namespace Gwenview | ||
50 | { | 52 | { | ||
51 | 53 | | |||
52 | struct ImporterPrivate | 54 | struct ImporterPrivate | ||
53 | { | 55 | { | ||
54 | Importer* q; | 56 | Importer* q; | ||
55 | QWidget* mAuthWindow; | 57 | QWidget* mAuthWindow; | ||
56 | std::unique_ptr<FileNameFormater> mFileNameFormater; | 58 | std::unique_ptr<FileNameFormater> mFileNameFormater; | ||
57 | QUrl mTempImportDirUrl; | 59 | QUrl mTempImportDirUrl; | ||
58 | QTemporaryDir* mTempImportDir; | 60 | QTemporaryDir* mTempImportDir; | ||
61 | QUrl mDestinationDirUrl; | ||||
59 | 62 | | |||
60 | /* @defgroup reset Should be reset in start() | 63 | /* @defgroup reset Should be reset in start() | ||
61 | * @{ */ | 64 | * @{ */ | ||
62 | QList<QUrl> mUrlList; | 65 | QList<QUrl> mUrlList; | ||
63 | QList<QUrl> mImportedUrlList; | 66 | QList<QUrl> mImportedUrlList; | ||
64 | QList<QUrl> mSkippedUrlList; | 67 | QList<QUrl> mSkippedUrlList; | ||
65 | QList<QUrl> mFailedUrlList; | 68 | QList<QUrl> mFailedUrlList; | ||
66 | QList<QUrl> mFailedSubFolderList; | 69 | QList<QUrl> mFailedSubFolderList; | ||
67 | int mRenamedCount; | 70 | int mRenamedCount; | ||
68 | int mProgress; | 71 | int mProgress; | ||
69 | int mJobProgress; | 72 | int mJobProgress; | ||
70 | /* @} */ | 73 | /* @} */ | ||
71 | 74 | | |||
72 | QUrl mCurrentUrl; | 75 | QUrl mCurrentUrl; | ||
73 | 76 | | |||
74 | bool createImportDir(const QUrl& url) | 77 | bool createImportDir(const QUrl& url) | ||
75 | { | 78 | { | ||
76 | Q_ASSERT(url.isLocalFile()); | 79 | KIO::Job* job = KIO::mkpath(url, QUrl(), KIO::HideProgressInfo); | ||
77 | // FIXME: Support remote urls | 80 | KJobWidgets::setWindow(job, mAuthWindow); | ||
ngraham: `job, mAuthWindow` | |||||
bdevries: Another nice catch! | |||||
78 | 81 | if (!job->exec()) { | |||
79 | if (!QDir().mkpath(url.toLocalFile())) { | | |||
80 | emit q->error(i18n("Could not create destination folder.")); | 82 | emit q->error(i18n("Could not create destination folder.")); | ||
81 | return false; | 83 | return false; | ||
82 | } | 84 | } | ||
83 | 85 | | |||
86 | // Check if local and fast url. The check for fast url is needed because | ||||
87 | // otherwise the retrieved date will not be correct: see implementation | ||||
88 | // of TimeUtils::dateTimeForFileItem | ||||
89 | if (UrlUtils::urlIsFastLocalFile(url)) { | ||||
84 | QString tempDirPath = url.toLocalFile() + "/.gwenview_importer-XXXXXX"; | 90 | QString tempDirPath = url.toLocalFile() + "/.gwenview_importer-XXXXXX"; | ||
85 | mTempImportDir = new QTemporaryDir(tempDirPath); | 91 | mTempImportDir = new QTemporaryDir(tempDirPath); | ||
92 | } else { | ||||
93 | mTempImportDir = new QTemporaryDir(); | ||||
94 | } | ||||
86 | 95 | | |||
87 | if (!mTempImportDir->isValid()) { | 96 | if (!mTempImportDir->isValid()) { | ||
88 | emit q->error(i18n("Could not create temporary upload folder.")); | 97 | emit q->error(i18n("Could not create temporary upload folder.")); | ||
89 | return false; | 98 | return false; | ||
90 | } | 99 | } | ||
91 | 100 | | |||
92 | mTempImportDirUrl = QUrl::fromLocalFile(mTempImportDir->path() + '/'); | 101 | mTempImportDirUrl = QUrl::fromLocalFile(mTempImportDir->path() + '/'); | ||
93 | if (!mTempImportDirUrl.isValid()) { | 102 | if (!mTempImportDirUrl.isValid()) { | ||
94 | emit q->error(i18n("Could not create temporary upload folder.")); | 103 | emit q->error(i18n("Could not create temporary upload folder.")); | ||
95 | return false; | 104 | return false; | ||
96 | } | 105 | } | ||
97 | 106 | | |||
98 | return true; | 107 | return true; | ||
99 | } | 108 | } | ||
100 | 109 | | |||
101 | void importNext() | 110 | void importNext() | ||
102 | { | 111 | { | ||
103 | if (mUrlList.empty()) { | 112 | if (mUrlList.empty()) { | ||
104 | q->finalizeImport(); | 113 | q->finalizeImport(); | ||
105 | return; | 114 | return; | ||
106 | } | 115 | } | ||
107 | mCurrentUrl = mUrlList.takeFirst(); | 116 | mCurrentUrl = mUrlList.takeFirst(); | ||
108 | QUrl dst = mTempImportDirUrl; | 117 | QUrl dst = mTempImportDirUrl; | ||
109 | dst.setPath(dst.path() + mCurrentUrl.fileName()); | 118 | dst.setPath(dst.path() + mCurrentUrl.fileName()); | ||
110 | KIO::Job* job = KIO::copy(mCurrentUrl, dst, KIO::HideProgressInfo|KIO::Overwrite); | 119 | KIO::Job* job = KIO::copy(mCurrentUrl, dst, KIO::HideProgressInfo|KIO::Overwrite); | ||
ngraham: Seems unrelated; let's do this in a separate patch | |||||
Yes, it's is indeed not directly related. This solves a bug that already existed before this patch. I'll take it out and re-submit. bdevries: Yes, it's is indeed not directly related. This solves a bug that already existed before this… | |||||
111 | KJobWidgets::setWindow(job, mAuthWindow); | 120 | KJobWidgets::setWindow(job, mAuthWindow); | ||
112 | QObject::connect(job, &KJob::result, | 121 | QObject::connect(job, &KJob::result, | ||
113 | q, &Importer::slotCopyDone); | 122 | q, &Importer::slotCopyDone); | ||
114 | QObject::connect(job, SIGNAL(percent(KJob*,ulong)), | 123 | QObject::connect(job, SIGNAL(percent(KJob*,ulong)), | ||
115 | q, SLOT(slotPercent(KJob*,ulong))); | 124 | q, SLOT(slotPercent(KJob*,ulong))); | ||
116 | } | 125 | } | ||
117 | 126 | | |||
118 | void renameImportedUrl(const QUrl& src) | 127 | void renameImportedUrl(const QUrl& src) | ||
119 | { | 128 | { | ||
120 | QUrl dst = src.resolved(QUrl("..")); | 129 | QUrl dst = mDestinationDirUrl; | ||
121 | QString fileName; | 130 | QString fileName; | ||
122 | if (mFileNameFormater.get()) { | 131 | if (mFileNameFormater.get()) { | ||
123 | KFileItem item(src); | 132 | KFileItem item(src); | ||
124 | item.setDelayedMimeTypes(true); | 133 | item.setDelayedMimeTypes(true); | ||
125 | // Get the document time, but do not cache the result because the | 134 | // Get the document time, but do not cache the result because the | ||
126 | // 'src' url is temporary: if we import "foo/image.jpg" and | 135 | // 'src' url is temporary: if we import "foo/image.jpg" and | ||
127 | // "bar/image.jpg", both images will be temporarily saved in the | 136 | // "bar/image.jpg", both images will be temporarily saved in the | ||
128 | // 'src' url. | 137 | // 'src' url. | ||
129 | QDateTime dateTime = TimeUtils::dateTimeForFileItem(item, TimeUtils::SkipCache); | 138 | QDateTime dateTime = TimeUtils::dateTimeForFileItem(item, TimeUtils::SkipCache); | ||
130 | fileName = mFileNameFormater->format(src, dateTime); | 139 | fileName = mFileNameFormater->format(src, dateTime); | ||
131 | } else { | 140 | } else { | ||
132 | fileName = src.fileName(); | 141 | fileName = src.fileName(); | ||
133 | } | 142 | } | ||
134 | dst.setPath(dst.path() + fileName); | 143 | dst.setPath(dst.path() + '/' + fileName); | ||
135 | 144 | | |||
136 | FileUtils::RenameResult result; | 145 | FileUtils::RenameResult result; | ||
137 | // Create additional subfolders if needed (e.g. when extra slashes in FileNameFormater) | 146 | // Create additional subfolders if needed (e.g. when extra slashes in FileNameFormater) | ||
138 | QUrl subFolder = dst.adjusted(QUrl::RemoveFilename); | 147 | QUrl subFolder = dst.adjusted(QUrl::RemoveFilename); | ||
139 | KIO::Job* job = KIO::mkpath(subFolder, QUrl(), KIO::HideProgressInfo); | 148 | KIO::Job* job = KIO::mkpath(subFolder, QUrl(), KIO::HideProgressInfo); | ||
140 | KJobWidgets::setWindow(job,mAuthWindow); | 149 | KJobWidgets::setWindow(job,mAuthWindow); | ||
141 | if (!job->exec()) { // if subfolder creation fails | 150 | if (!job->exec()) { // if subfolder creation fails | ||
142 | qWarning() << "Could not create subfolder:" << subFolder; | 151 | qWarning() << "Could not create subfolder:" << subFolder; | ||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Line(s) | 195 | if (format.isEmpty()) { | |||
187 | d->mFileNameFormater.reset(nullptr); | 196 | d->mFileNameFormater.reset(nullptr); | ||
188 | } else { | 197 | } else { | ||
189 | d->mFileNameFormater.reset(new FileNameFormater(format)); | 198 | d->mFileNameFormater.reset(new FileNameFormater(format)); | ||
190 | } | 199 | } | ||
191 | } | 200 | } | ||
192 | 201 | | |||
193 | void Importer::start(const QList<QUrl>& list, const QUrl& destination) | 202 | void Importer::start(const QList<QUrl>& list, const QUrl& destination) | ||
194 | { | 203 | { | ||
204 | d->mDestinationDirUrl = destination; | ||||
195 | d->mUrlList = list; | 205 | d->mUrlList = list; | ||
196 | d->mImportedUrlList.clear(); | 206 | d->mImportedUrlList.clear(); | ||
197 | d->mSkippedUrlList.clear(); | 207 | d->mSkippedUrlList.clear(); | ||
198 | d->mFailedUrlList.clear(); | 208 | d->mFailedUrlList.clear(); | ||
199 | d->mFailedSubFolderList.clear(); | 209 | d->mFailedSubFolderList.clear(); | ||
200 | d->mRenamedCount = 0; | 210 | d->mRenamedCount = 0; | ||
201 | d->mProgress = 0; | 211 | d->mProgress = 0; | ||
202 | d->mJobProgress = 0; | 212 | d->mJobProgress = 0; | ||
▲ Show 20 Lines • Show All 76 Lines • Show Last 20 Lines |
job, mAuthWindow