Changeset View
Changeset View
Standalone View
Standalone View
document/kpDocument_Save.cpp
Context not available. | |||||
46 | #include <QTemporaryFile> | 46 | #include <QTemporaryFile> | ||
---|---|---|---|---|---|
47 | #include <QTransform> | 47 | #include <QTransform> | ||
48 | #include <QMimeDatabase> | 48 | #include <QMimeDatabase> | ||
49 | #include <QImageWriter> | ||||
49 | 50 | | |||
50 | #include "kpLogCategories.h" | 51 | #include "kpLogCategories.h" | ||
51 | #include <kimageio.h> // kdelibs4support | 52 | #include <KIO/StatJob> | ||
52 | #include <kio/netaccess.h> // kdelibs4support | 53 | #include <KIO/FileCopyJob> | ||
54 | #include <KJobWidgets> | ||||
53 | #include <KLocalizedString> | 55 | #include <KLocalizedString> | ||
54 | #include <kmessagebox.h> | 56 | #include <kmessagebox.h> | ||
57 | #include <KService> | ||||
58 | #include <KServiceTypeTrader> | ||||
55 | 59 | | |||
56 | #include "imagelib/kpColor.h" | 60 | #include "imagelib/kpColor.h" | ||
57 | #include "widgets/toolbars/kpColorToolBar.h" | 61 | #include "widgets/toolbars/kpColorToolBar.h" | ||
Context not available. | |||||
175 | *userCancelled = false; | 179 | *userCancelled = false; | ||
176 | } | 180 | } | ||
177 | 181 | | |||
178 | QStringList types = KImageIO::typeForMime (saveOptions.mimeType ()); | 182 | if (saveOptions.mimeType().isEmpty()) { | ||
183 | return false; | ||||
184 | } | ||||
185 | | ||||
186 | QList<QByteArray> types; | ||||
187 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) | ||||
188 | types = QImageWriter::imageFormatsForMimeType(saveOptions.mimeType().toLocal8Bit()); | ||||
189 | #else | ||||
190 | QStringList typesStrings; | ||||
191 | const KService::List services = KServiceTypeTrader::self()->query("QImageIOPlugins"); | ||||
192 | for (const KService::Ptr &service : services) { | ||||
193 | if (saveOptions.mimeType() != service->property("X-KDE-MimeType").toString()) { | ||||
194 | continue; | ||||
195 | } | ||||
196 | typesStrings = service->property("X-KDE-ImageFormat").toStringList(); | ||||
197 | if (!typesStrings.isEmpty()) { | ||||
198 | break; | ||||
199 | } | ||||
200 | } | ||||
201 | for (const QString &type : typesStrings) { | ||||
202 | types.append(type.toLatin1()); | ||||
203 | } | ||||
204 | #endif | ||||
205 | | ||||
179 | #if DEBUG_KP_DOCUMENT | 206 | #if DEBUG_KP_DOCUMENT | ||
180 | qCDebug(kpLogDocument) << "\ttypes=" << types; | 207 | qCDebug(kpLogDocument) << "\ttypes=" << types; | ||
181 | #endif | 208 | #endif | ||
209 | | ||||
182 | if (types.isEmpty ()) { | 210 | if (types.isEmpty ()) { | ||
183 | return false; | 211 | return false; | ||
184 | } | 212 | } | ||
185 | // It's safe to arbitrarily choose the 0th type as any type in the list | 213 | // It's safe to arbitrarily choose the 0th type as any type in the list | ||
186 | // should invoke the same KImageIO image loader. | 214 | // should invoke the same KImageIO image loader. | ||
187 | const QString type = types [0]; | 215 | const QByteArray type = types [0]; | ||
188 | 216 | | |||
189 | #if DEBUG_KP_DOCUMENT | 217 | #if DEBUG_KP_DOCUMENT | ||
190 | qCDebug(kpLogDocument) << "\tmimeType=" << saveOptions.mimeType () | 218 | qCDebug(kpLogDocument) << "\tmimeType=" << saveOptions.mimeType () | ||
Context not available. | |||||
271 | #if DEBUG_KP_DOCUMENT | 299 | #if DEBUG_KP_DOCUMENT | ||
272 | qCDebug(kpLogDocument) << "\tsaving"; | 300 | qCDebug(kpLogDocument) << "\tsaving"; | ||
273 | #endif | 301 | #endif | ||
274 | if (!imageToSave.save (device, type.toLatin1 (), quality)) | 302 | if (!imageToSave.save (device, type, quality)) | ||
275 | { | 303 | { | ||
276 | #if DEBUG_KP_DOCUMENT | 304 | #if DEBUG_KP_DOCUMENT | ||
277 | qCDebug(kpLogDocument) << "\tQImage::save() returned false"; | 305 | qCDebug(kpLogDocument) << "\tQImage::save() returned false"; | ||
Context not available. | |||||
318 | // TODO: Use KIO::NetAccess:mostLocalURL() for accessing home:/ (and other | 346 | // TODO: Use KIO::NetAccess:mostLocalURL() for accessing home:/ (and other | ||
319 | // such local URLs) for efficiency and because only local writes | 347 | // such local URLs) for efficiency and because only local writes | ||
320 | // are atomic. | 348 | // are atomic. | ||
349 | // -> But we use QSaveFile for atomicness, and that doesn't seem to be able | ||||
350 | // to warn about file already existing, so we can't get 100% atomic | ||||
321 | #if DEBUG_KP_DOCUMENT | 351 | #if DEBUG_KP_DOCUMENT | ||
322 | qCDebug(kpLogDocument) << "kpDocument::savePixmapToFile (" | 352 | qCDebug(kpLogDocument) << "kpDocument::savePixmapToFile (" | ||
323 | << url | 353 | << url | ||
Context not available. | |||||
328 | metaInfo.printDebug (QLatin1String ("\tmetaInfo")); | 358 | metaInfo.printDebug (QLatin1String ("\tmetaInfo")); | ||
329 | #endif | 359 | #endif | ||
330 | 360 | | |||
331 | if (overwritePrompt && | 361 | if (overwritePrompt) { | ||
332 | KIO::NetAccess::exists (url, KIO::NetAccess::DestinationSide/*write*/, parent)) | 362 | // 0 == only check if the file exists, don't bother with file metadata | ||
333 | { | 363 | KIO::StatJob *statJob = KIO::stat(url, KIO::StatJob::SourceSide, 0); | ||
334 | int result = KMessageBox::warningContinueCancel (parent, | 364 | KJobWidgets::setWindow(statJob, parent); | ||
335 | i18n ("A document called \"%1\" already exists.\n" | 365 | const bool exists = statJob->exec(); | ||
336 | "Do you want to overwrite it?", | | |||
337 | kpUrlFormatter::PrettyFilename (url)), | | |||
338 | QString(), | | |||
339 | KStandardGuiItem::overwrite ()); | | |||
340 | 366 | | |||
341 | if (result != KMessageBox::Continue) | 367 | if (exists) { | ||
342 | { | 368 | int result = KMessageBox::warningContinueCancel (parent, | ||
343 | #if DEBUG_KP_DOCUMENT | 369 | i18n ("A document called \"%1\" already exists.\n" | ||
344 | qCDebug(kpLogDocument) << "\tuser doesn't want to overwrite"; | 370 | "Do you want to overwrite it?", | ||
345 | #endif | 371 | kpUrlFormatter::PrettyFilename (url)), | ||
372 | QString(), | ||||
373 | KStandardGuiItem::overwrite ()); | ||||
346 | 374 | | |||
347 | return false; | 375 | if (result != KMessageBox::Continue) | ||
376 | { | ||||
377 | #if DEBUG_KP_DOCUMENT | ||||
378 | qCDebug(kpLogDocument) << "\tuser doesn't want to overwrite"; | ||||
379 | #endif | ||||
380 | | ||||
381 | return false; | ||||
382 | } | ||||
348 | } | 383 | } | ||
349 | } | 384 | } | ||
350 | 385 | | |||
Context not available. | |||||
463 | // TODO: No one seems to know how to do this atomically | 498 | // TODO: No one seems to know how to do this atomically | ||
464 | // [http://lists.kde.org/?l=kde-core-devel&m=117845162728484&w=2]. | 499 | // [http://lists.kde.org/?l=kde-core-devel&m=117845162728484&w=2]. | ||
465 | // At least, fish:// (ssh) is definitely not atomic. | 500 | // At least, fish:// (ssh) is definitely not atomic. | ||
466 | if (!KIO::NetAccess::upload (tempFileName, url, parent)) | 501 | KIO::FileCopyJob *uploadJob = KIO::file_copy(QUrl::fromLocalFile(tempFileName), url, -1, KIO::Overwrite); | ||
502 | KJobWidgets::setWindow(uploadJob, parent); | ||||
503 | if (!uploadJob->exec()) | ||||
467 | { | 504 | { | ||
468 | #if DEBUG_KP_DOCUMENT | 505 | #if DEBUG_KP_DOCUMENT | ||
469 | qCDebug(kpLogDocument) << "\treturning false because could not upload"; | 506 | qCDebug(kpLogDocument) << "\treturning false because could not upload"; | ||
Context not available. |