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 | int mRenamedCount; | 68 | int mRenamedCount; | ||
66 | int mProgress; | 69 | int mProgress; | ||
67 | int mJobProgress; | 70 | int mJobProgress; | ||
68 | /* @} */ | 71 | /* @} */ | ||
69 | 72 | | |||
70 | QUrl mCurrentUrl; | 73 | QUrl mCurrentUrl; | ||
71 | 74 | | |||
72 | bool createImportDir(const QUrl& url) | 75 | bool createImportDir(const QUrl& url) | ||
73 | { | 76 | { | ||
74 | Q_ASSERT(url.isLocalFile()); | 77 | KIO::Job* job = KIO::mkpath(url, QUrl(), KIO::HideProgressInfo); | ||
75 | // FIXME: Support remote urls | 78 | KJobWidgets::setWindow(job, mAuthWindow); | ||
ngraham: `job, mAuthWindow` | |||||
bdevries: Another nice catch! | |||||
76 | 79 | if (!job->exec()) { | |||
77 | if (!QDir().mkpath(url.toLocalFile())) { | | |||
78 | emit q->error(i18n("Could not create destination folder.")); | 80 | emit q->error(i18n("Could not create destination folder.")); | ||
79 | return false; | 81 | return false; | ||
80 | } | 82 | } | ||
81 | 83 | | |||
84 | // Check if local and fast url. The check for fast url is needed because | ||||
85 | // otherwise the retrieved date will not be correct: see implementation | ||||
86 | // of TimeUtils::dateTimeForFileItem | ||||
87 | if (UrlUtils::urlIsFastLocalFile(url)) { | ||||
82 | QString tempDirPath = url.toLocalFile() + "/.gwenview_importer-XXXXXX"; | 88 | QString tempDirPath = url.toLocalFile() + "/.gwenview_importer-XXXXXX"; | ||
83 | mTempImportDir = new QTemporaryDir(tempDirPath); | 89 | mTempImportDir = new QTemporaryDir(tempDirPath); | ||
90 | } else { | ||||
91 | mTempImportDir = new QTemporaryDir(); | ||||
92 | } | ||||
84 | 93 | | |||
85 | if (!mTempImportDir->isValid()) { | 94 | if (!mTempImportDir->isValid()) { | ||
86 | emit q->error(i18n("Could not create temporary upload folder.")); | 95 | emit q->error(i18n("Could not create temporary upload folder.")); | ||
87 | return false; | 96 | return false; | ||
88 | } | 97 | } | ||
89 | 98 | | |||
90 | mTempImportDirUrl = QUrl::fromLocalFile(mTempImportDir->path() + '/'); | 99 | mTempImportDirUrl = QUrl::fromLocalFile(mTempImportDir->path() + '/'); | ||
91 | if (!mTempImportDirUrl.isValid()) { | 100 | if (!mTempImportDirUrl.isValid()) { | ||
92 | emit q->error(i18n("Could not create temporary upload folder.")); | 101 | emit q->error(i18n("Could not create temporary upload folder.")); | ||
93 | return false; | 102 | return false; | ||
94 | } | 103 | } | ||
95 | 104 | | |||
96 | return true; | 105 | return true; | ||
97 | } | 106 | } | ||
98 | 107 | | |||
99 | void importNext() | 108 | void importNext() | ||
100 | { | 109 | { | ||
101 | if (mUrlList.empty()) { | 110 | if (mUrlList.empty()) { | ||
102 | q->finalizeImport(); | 111 | q->finalizeImport(); | ||
103 | return; | 112 | return; | ||
104 | } | 113 | } | ||
105 | mCurrentUrl = mUrlList.takeFirst(); | 114 | mCurrentUrl = mUrlList.takeFirst(); | ||
106 | QUrl dst = mTempImportDirUrl; | 115 | QUrl dst = mTempImportDirUrl; | ||
107 | dst.setPath(dst.path() + mCurrentUrl.fileName()); | 116 | dst.setPath(dst.path() + mCurrentUrl.fileName()); | ||
108 | KIO::Job* job = KIO::copy(mCurrentUrl, dst, KIO::HideProgressInfo); | 117 | KIO::Job* job = KIO::copy(mCurrentUrl, dst, KIO::HideProgressInfo); | ||
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… | |||||
109 | KJobWidgets::setWindow(job, mAuthWindow); | 118 | KJobWidgets::setWindow(job, mAuthWindow); | ||
110 | QObject::connect(job, &KJob::result, | 119 | QObject::connect(job, &KJob::result, | ||
111 | q, &Importer::slotCopyDone); | 120 | q, &Importer::slotCopyDone); | ||
112 | QObject::connect(job, SIGNAL(percent(KJob*,ulong)), | 121 | QObject::connect(job, SIGNAL(percent(KJob*,ulong)), | ||
113 | q, SLOT(slotPercent(KJob*,ulong))); | 122 | q, SLOT(slotPercent(KJob*,ulong))); | ||
114 | } | 123 | } | ||
115 | 124 | | |||
116 | void renameImportedUrl(const QUrl& src) | 125 | void renameImportedUrl(const QUrl& src) | ||
117 | { | 126 | { | ||
118 | QUrl dst = src.resolved(QUrl("..")); | 127 | QUrl dst = mDestinationDirUrl; | ||
119 | QString fileName; | 128 | QString fileName; | ||
120 | if (mFileNameFormater.get()) { | 129 | if (mFileNameFormater.get()) { | ||
121 | KFileItem item(src); | 130 | KFileItem item(src); | ||
122 | item.setDelayedMimeTypes(true); | 131 | item.setDelayedMimeTypes(true); | ||
123 | // Get the document time, but do not cache the result because the | 132 | // Get the document time, but do not cache the result because the | ||
124 | // 'src' url is temporary: if we import "foo/image.jpg" and | 133 | // 'src' url is temporary: if we import "foo/image.jpg" and | ||
125 | // "bar/image.jpg", both images will be temporarily saved in the | 134 | // "bar/image.jpg", both images will be temporarily saved in the | ||
126 | // 'src' url. | 135 | // 'src' url. | ||
127 | QDateTime dateTime = TimeUtils::dateTimeForFileItem(item, TimeUtils::SkipCache); | 136 | QDateTime dateTime = TimeUtils::dateTimeForFileItem(item, TimeUtils::SkipCache); | ||
128 | fileName = mFileNameFormater->format(src, dateTime); | 137 | fileName = mFileNameFormater->format(src, dateTime); | ||
129 | } else { | 138 | } else { | ||
130 | fileName = src.fileName(); | 139 | fileName = src.fileName(); | ||
131 | } | 140 | } | ||
132 | dst.setPath(dst.path() + fileName); | 141 | dst.setPath(dst.path() + '/' + fileName); | ||
133 | 142 | | |||
134 | FileUtils::RenameResult result; | 143 | FileUtils::RenameResult result; | ||
135 | // Create additional subfolders if needed (e.g. when extra slashes in FileNameFormater) | 144 | // Create additional subfolders if needed (e.g. when extra slashes in FileNameFormater) | ||
136 | QUrl subFolder = dst.adjusted(QUrl::RemoveFilename); | 145 | QUrl subFolder = dst.adjusted(QUrl::RemoveFilename); | ||
137 | KIO::Job* job = KIO::mkpath(subFolder, QUrl(), KIO::HideProgressInfo); | 146 | KIO::Job* job = KIO::mkpath(subFolder, QUrl(), KIO::HideProgressInfo); | ||
138 | KJobWidgets::setWindow(job,mAuthWindow); | 147 | KJobWidgets::setWindow(job,mAuthWindow); | ||
139 | if (!job->exec()) { // if subfolder creation fails | 148 | if (!job->exec()) { // if subfolder creation fails | ||
140 | qWarning() << "Could not create subfolder:" << subFolder; | 149 | qWarning() << "Could not create subfolder:" << subFolder; | ||
Show All 40 Lines | 189 | if (format.isEmpty()) { | |||
181 | d->mFileNameFormater.reset(nullptr); | 190 | d->mFileNameFormater.reset(nullptr); | ||
182 | } else { | 191 | } else { | ||
183 | d->mFileNameFormater.reset(new FileNameFormater(format)); | 192 | d->mFileNameFormater.reset(new FileNameFormater(format)); | ||
184 | } | 193 | } | ||
185 | } | 194 | } | ||
186 | 195 | | |||
187 | void Importer::start(const QList<QUrl>& list, const QUrl& destination) | 196 | void Importer::start(const QList<QUrl>& list, const QUrl& destination) | ||
188 | { | 197 | { | ||
198 | d->mDestinationDirUrl = destination; | ||||
189 | d->mUrlList = list; | 199 | d->mUrlList = list; | ||
190 | d->mImportedUrlList.clear(); | 200 | d->mImportedUrlList.clear(); | ||
191 | d->mSkippedUrlList.clear(); | 201 | d->mSkippedUrlList.clear(); | ||
192 | d->mRenamedCount = 0; | 202 | d->mRenamedCount = 0; | ||
193 | d->mProgress = 0; | 203 | d->mProgress = 0; | ||
194 | d->mJobProgress = 0; | 204 | d->mJobProgress = 0; | ||
195 | 205 | | |||
196 | emitProgressChanged(); | 206 | emitProgressChanged(); | ||
▲ Show 20 Lines • Show All 63 Lines • Show Last 20 Lines |
job, mAuthWindow