Krita Source Code Documentation
Loading...
Searching...
No Matches
KisImportExportManager Class Reference

The class managing all the filters. More...

#include <KisImportExportManager.h>

+ Inheritance diagram for KisImportExportManager:

Classes

struct  ConversionResult
 

Public Types

enum  Direction { Import = 1 , Export = 2 }
 

Public Member Functions

KisImportExportErrorCode exportDocument (const QString &location, const QString &realLocation, const QByteArray &mimeType, bool showWarnings=true, KisPropertiesConfigurationSP exportConfiguration=0, bool isAdvancedExporting=false)
 Exports the given file/document to the specified URL/mimetype.
 
QFuture< KisImportExportErrorCodeexportDocumentAsync (const QString &location, const QString &realLocation, const QByteArray &mimeType, KisImportExportErrorCode &status, bool showWarnings=true, KisPropertiesConfigurationSP exportConfiguration=0, bool isAdvancedExporting=false)
 
KisImportExportErrorCode importDocument (const QString &location, const QString &mimeType)
 
 KisImportExportManager (KisDocument *document)
 
 ~KisImportExportManager () override
 

Public Attributes

QSharedPointer< KisImportExportFiltercachedExportFilter
 
QString cachedExportFilterMimeType
 
KoUpdaterPtr updater
 

Static API

KisDocumentm_document
 
Private *const d
 
static QStringList m_importMimeTypes
 A static cache for the availability checks of filters.
 
static QStringList m_exportMimeTypes
 
bool batchMode (void) const
 
void setUpdater (KoUpdaterPtr updater)
 
static QStringList supportedMimeTypes (Direction direction)
 
static KisImportExportFilterfilterForMimeType (const QString &mimetype, Direction direction)
 filterForMimeType loads the relevant import/export plugin and returns it. The caller is responsible for deleting it!
 
static void fillStaticExportConfigurationProperties (KisPropertiesConfigurationSP exportConfiguration, KisImageSP image)
 
static QString askForAudioFileName (const QString &defaultDir, QWidget *parent)
 
static QString getUriForAdditionalFile (const QString &defaultUri, QWidget *parent)
 
ConversionResult convert (Direction direction, const QString &location, const QString &realLocation, const QString &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration, bool isAsync, bool isAdvancedExporting=false)
 
void fillStaticExportConfigurationProperties (KisPropertiesConfigurationSP exportConfiguration)
 
bool askUserAboutExportConfiguration (QSharedPointer< KisImportExportFilter > filter, KisPropertiesConfigurationSP exportConfiguration, const QByteArray &from, const QByteArray &to, bool batchMode, const bool showWarnings, bool *alsoAsKra, bool isAdvancedExporting=false)
 
KisImportExportErrorCode doImport (const QString &location, QSharedPointer< KisImportExportFilter > filter)
 
KisImportExportErrorCode doExport (const QString &location, QSharedPointer< KisImportExportFilter > filter, KisPropertiesConfigurationSP exportConfiguration, const QString alsoAsKraLocation)
 
KisImportExportErrorCode doExportImpl (const QString &location, QSharedPointer< KisImportExportFilter > filter, KisPropertiesConfigurationSP exportConfiguration)
 
QString getAlsoAsKraLocation (const QString location) const
 
 KisImportExportManager (const KisImportExportManager &rhs)
 
KisImportExportManageroperator= (const KisImportExportManager &rhs)
 

Additional Inherited Members

- Private Member Functions inherited from Private
 Private (KisCanvas2 *c)
 
- Private Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Detailed Description

The class managing all the filters.

This class manages all filters for a Calligra application. Normally you will not have to use it, since KisMainWindow takes care of loading and saving documents.

KisFilter

Author
Kalle Dalheimer kalle.nosp@m.@kde.nosp@m..org
Torben Weis weis@.nosp@m.kde..nosp@m.org
Werner Trobin trobi.nosp@m.n@kd.nosp@m.e.org

Definition at line 96 of file KisImportExportManager.cpp.

Member Enumeration Documentation

◆ Direction

This enum is used to distinguish the import/export cases

Enumerator
Import 
Export 

Definition at line 45 of file KisImportExportManager.h.

Constructor & Destructor Documentation

◆ KisImportExportManager() [1/2]

KisImportExportManager::KisImportExportManager ( KisDocument * document)
explicit

Create a filter manager for a document

Definition at line 148 of file KisImportExportManager.cpp.

149 : m_document(document)
150 , d(new Private)
151{
152}

◆ ~KisImportExportManager()

KisImportExportManager::~KisImportExportManager ( )
override

Definition at line 154 of file KisImportExportManager.cpp.

155{
156 delete d;
157}

References d.

◆ KisImportExportManager() [2/2]

KisImportExportManager::KisImportExportManager ( const KisImportExportManager & rhs)
private

Member Function Documentation

◆ askForAudioFileName()

QString KisImportExportManager::askForAudioFileName ( const QString & defaultDir,
QWidget * parent )
static

Definition at line 287 of file KisImportExportManager.cpp.

288{
289 KoFileDialog dialog(parent, KoFileDialog::ImportFiles, "ImportAudio");
290
291 if (!defaultDir.isEmpty()) {
292 dialog.setDefaultDir(defaultDir);
293 }
294
295 QStringList mimeTypes;
296 mimeTypes << "audio/mpeg";
297 mimeTypes << "audio/ogg";
298 mimeTypes << "audio/vorbis";
299 mimeTypes << "audio/vnd.wave";
300 mimeTypes << "audio/flac";
301
302 dialog.setMimeTypeFilters(mimeTypes);
303 dialog.setCaption(i18nc("@title:window", "Open Audio"));
304
305 return dialog.filename();
306}

References KoFileDialog::ImportFiles.

◆ askUserAboutExportConfiguration()

bool KisImportExportManager::askUserAboutExportConfiguration ( QSharedPointer< KisImportExportFilter > filter,
KisPropertiesConfigurationSP exportConfiguration,
const QByteArray & from,
const QByteArray & to,
bool batchMode,
const bool showWarnings,
bool * alsoAsKra,
bool isAdvancedExporting = false )
private

Definition at line 523 of file KisImportExportManager.cpp.

532{
533
534 // prevents the animation renderer from running this code
535
536
537 const QString mimeUserDescription = KisMimeDatabase::descriptionForMimeType(to);
538
539 QStringList warnings;
540 QStringList errors;
541
542 {
543 KisPreExportChecker checker;
544 checker.check(m_document->image(), filter->exportChecks());
545
546 warnings = checker.warnings();
547 errors = checker.errors();
548 }
549
550 KisConfigWidget *wdg = 0;
551
552 if (QThread::currentThread() == qApp->thread()) {
553 wdg = filter->createConfigurationWidget(0, from, to);
554
556 if (wdg && kisMain) {
557 KisViewManager *manager = kisMain->viewManager();
558 wdg->setView(manager);
559 }
560 }
561
562 // Extra checks that cannot be done by the checker, because the checker only has access to the image.
563 if (!m_document->assistants().isEmpty() && to != m_document->nativeFormatMimeType()) {
564 warnings.append(i18nc("image conversion warning", "The image contains <b>assistants</b>. The assistants will not be saved."));
565 }
567 warnings.append(i18nc("image conversion warning", "The image contains <b>reference images</b>. The reference images will not be saved."));
568 }
569 if (m_document->guidesConfig().hasGuides() && !filter->exportSupportsGuides()) {
570 warnings.append(i18nc("image conversion warning", "The image contains <b>guides</b>. The guides will not be saved."));
571 }
573 warnings.append(i18nc("image conversion warning", "The image contains a <b>custom grid configuration</b>. The configuration will not be saved."));
574 }
575
576 bool shouldFlattenTheImageBeforeScaling = false;
577
578 if (isAdvancedExporting) {
579 QMap<QString, KisExportCheckBase *> exportChecks = filter->exportChecks();
580
581 const bool filterSupportsMultilayerExport =
582 exportChecks.contains("MultiLayerCheck") &&
583 exportChecks["MultiLayerCheck"]->checkNeeded(m_document->image()) &&
584 exportChecks["MultiLayerCheck"]->check(m_document->image()) == KisExportCheckBase::SUPPORTED;
585
586 if (!filterSupportsMultilayerExport) {
587 shouldFlattenTheImageBeforeScaling = true;
588 } else {
589 if (KisLayerUtils::findNodeByType<KisAdjustmentLayer>(m_document->image()->root())) {
590 shouldFlattenTheImageBeforeScaling = true;
591 warnings.append(i18nc("image conversion warning", "Trying to perform an Advanced Export with the image containing a <b>filter layer</b>. The image will be <b>flattened</b> before resizing."));
592 }
593 if (KisLayerUtils::findNodeByType<KisFilterMask>(m_document->image()->root())) {
594 shouldFlattenTheImageBeforeScaling = true;
595 warnings.append(i18nc("image conversion warning", "Trying to perform an Advanced Export with the image containing a <b>filter mask</b>. The image will be <b>flattened</b> before resizing."));
596 }
597 bool hasLayerStyles =
599 [] (KisNodeSP node) {
600 KisLayer *layer = dynamic_cast<KisLayer*>(node.data());
601 return layer && layer->layerStyle();
602 });
603
604 if (hasLayerStyles) {
605 shouldFlattenTheImageBeforeScaling = true;
606 warnings.append(i18nc("image conversion warning", "Trying to perform an Advanced Export with the image containing a <b>layer style</b>. The image will be <b>flattened</b> before resizing."));
607 }
608 }
609 }
610
611 if (!batchMode && !errors.isEmpty()) {
612 QString error = "<html><body><p><b>"
613 + i18n("Error: cannot save this image as a %1.", mimeUserDescription)
614 + "</b> " + i18n("Reasons:") + "</p>"
615 + "<p/><ul>";
616 Q_FOREACH(const QString &w, errors) {
617 error += "\n<li>" + w + "</li>";
618 }
619
620 error += "</ul>";
621
622 QMessageBox::critical(KisPart::instance()->currentMainwindow(), i18nc("@title:window", "Krita: Export Error"), error);
623 return false;
624 }
625
626 if (!batchMode && (wdg || !warnings.isEmpty() || isAdvancedExporting)) {
627 QWidget *page = new QWidget();
628 QVBoxLayout *layout = new QVBoxLayout(page);
629
630 if (showWarnings && !warnings.isEmpty()) {
631 QHBoxLayout *hLayout = new QHBoxLayout();
632
633 QLabel *labelWarning = new QLabel();
634 labelWarning->setPixmap(KisIconUtils::loadIcon("dialog-warning").pixmap(48, 48));
635 hLayout->addWidget(labelWarning);
636
637 KisPopupButton *bn = new KisPopupButton(0);
638
639 bn->setText(i18nc("Keep the extra space at the end of the sentence, please", "Warning: saving as a %1 will lose information from your image. ", mimeUserDescription));
640 bn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
641
642 hLayout->addWidget(bn);
643
644 layout->addLayout(hLayout);
645
646 QTextBrowser *browser = new QTextBrowser();
647 browser->setMinimumWidth(bn->width());
648 bn->setPopupWidget(browser);
649
650 QString warning = "<html><body><p><b>"
651 + i18n("You will lose information when saving this image as a %1.", mimeUserDescription);
652
653 if (warnings.size() == 1) {
654 warning += "</b> " + i18n("Reason:") + "</p>";
655 }
656 else {
657 warning += "</b> " + i18n("Reasons:") + "</p>";
658 }
659 warning += "<p/><ul>";
660
661 Q_FOREACH(const QString &w, warnings) {
662 warning += "\n<li>" + w + "</li>";
663 }
664
665 warning += "</ul>";
666 browser->setHtml(warning);
667 }
668
669 QTabWidget *box = new QTabWidget;
670 if (wdg) {
671 wdg->setConfiguration(exportConfiguration);
672 box->addTab(wdg,i18n("Options"));
673 }
674
675 WdgImageSize *wdgImageSize = nullptr;
676
677 if (isAdvancedExporting) {
678 wdgImageSize = new WdgImageSize(box, m_document->image()->width(), m_document->image()->height(), m_document->image()->yRes());
679
680 box->addTab(wdgImageSize,i18n("Resize"));
681 }
682 layout->addWidget(box);
683
684 QCheckBox *chkAlsoAsKra = 0;
685 if (showWarnings && !warnings.isEmpty()) {
686 chkAlsoAsKra = new QCheckBox(i18n("Also save your image as a Krita file."));
687 chkAlsoAsKra->setChecked(KisConfig(true).readEntry<bool>("AlsoSaveAsKra", false));
688 layout->addWidget(chkAlsoAsKra);
689 }
690
691 KoDialog dlg(qApp->activeWindow());
692 dlg.setMainWidget(page);
693 page->setParent(&dlg);
694 dlg.setButtons(KoDialog::Ok | KoDialog::Cancel);
695 dlg.setWindowTitle(mimeUserDescription);
696
697 if (showWarnings || wdg || isAdvancedExporting) {
698 if (!dlg.exec()) {
699 return false;
700 }
701 }
702
703 *alsoAsKra = false;
704 if (chkAlsoAsKra) {
705 KisConfig(false).writeEntry<bool>("AlsoSaveAsKra", chkAlsoAsKra->isChecked());
706 *alsoAsKra = chkAlsoAsKra->isChecked();
707 }
708
709 KIS_SAFE_ASSERT_RECOVER_NOOP(bool(isAdvancedExporting) == bool(wdgImageSize));
710
711 if (isAdvancedExporting && wdgImageSize) {
712 if (shouldFlattenTheImageBeforeScaling) {
715 }
716
717 const QSize desiredSize(wdgImageSize->desiredWidth(), wdgImageSize->desiredHeight());
718 double res = wdgImageSize->desiredResolution();
719 m_document->savingImage()->scaleImage(desiredSize,res,res,wdgImageSize->filterType());
723 }
724
725 if (wdg) {
726 *exportConfiguration = *wdg->configuration();
727 }
728 }
729
730 return true;
731}
virtual void setView(KisViewManager *view)
virtual KisPropertiesConfigurationSP configuration() const =0
virtual void setConfiguration(const KisPropertiesConfigurationSP config)=0
void writeEntry(const QString &name, const T &value)
Definition kis_config.h:865
KisSharedPtr< KisReferenceImagesLayer > referenceImagesLayer() const
KisImageSP image
KisGridConfig gridConfig
static QByteArray nativeFormatMimeType()
KisImageSP savingImage
QList< KisPaintingAssistantSP > assistants
KisGuidesConfig guidesConfig
bool isDefault() const
void waitForDone()
void flatten(KisNodeSP activeNode)
qint32 width() const
void scaleImage(const QSize &size, qreal xres, qreal yres, KisFilterStrategy *filterStrategy)
start asynchronous operation on scaling the image
double yRes() const
qint32 height() const
Main window for Krita.
KisViewManager * viewManager
static QString descriptionForMimeType(const QString &mimeType)
Find the user-readable description for the given mimetype.
static KisPart * instance()
Definition KisPart.cpp:131
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:459
void setPopupWidget(QWidget *widget)
bool check(KisImageSP image, QMap< QString, KisExportCheckBase * > filterChecks)
check checks the image against the capabilities of the export filter
QStringList errors() const
QStringList warnings() const
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
@ Ok
Show Ok button. (this button accept()s the dialog; result set to QDialog::Accepted)
Definition KoDialog.h:127
@ Cancel
Show Cancel-button. (this button reject()s the dialog; result set to QDialog::Rejected)
Definition KoDialog.h:130
KisFilterStrategy * filterType()
qint32 desiredWidth()
double desiredResolution()
qint32 desiredHeight()
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
KisSharedPtr< KisNode > KisNodeSP
Definition kis_types.h:86
QIcon loadIcon(const QString &name)
KisNodeSP recursiveFindNode(KisNodeSP node, std::function< bool(KisNodeSP)> func)
void forceAllDelayedNodesUpdate(KisNodeSP root)

References KisDocument::assistants, batchMode(), KoDialog::Cancel, KisPreExportChecker::check(), KisConfigWidget::configuration(), KisPart::currentMainwindow(), KisMimeDatabase::descriptionForMimeType(), WdgImageSize::desiredHeight(), WdgImageSize::desiredResolution(), WdgImageSize::desiredWidth(), KisPreExportChecker::errors(), WdgImageSize::filterType(), KisImage::flatten(), KisLayerUtils::forceAllDelayedNodesUpdate(), KisDocument::gridConfig, KisDocument::guidesConfig, KisGuidesConfig::hasGuides(), KisImage::height(), KisDocument::image, KisPart::instance(), KisGridConfig::isDefault(), KIS_SAFE_ASSERT_RECOVER_NOOP, KisIconUtils::loadIcon(), m_document, KisDocument::nativeFormatMimeType(), KoDialog::Ok, KisLayerUtils::recursiveFindNode(), KisDocument::referenceImagesLayer(), KisNodeFacade::root, KisDocument::savingImage, KisImage::scaleImage(), KoDialog::setButtons(), KisConfigWidget::setConfiguration(), KoDialog::setMainWidget(), KisPopupButton::setPopupWidget(), KisConfigWidget::setView(), KoShapeContainer::shapeCount(), KisExportCheckBase::SUPPORTED, KisMainWindow::viewManager, KisImage::waitForDone(), KisPreExportChecker::warnings(), KisImage::width(), KisConfig::writeEntry(), and KisImage::yRes().

◆ batchMode()

bool KisImportExportManager::batchMode ( void ) const

Get if the filter manager is batch mode (true) or in interactive mode (true)

Definition at line 277 of file KisImportExportManager.cpp.

278{
279 return m_document->fileBatchMode();
280}
bool fileBatchMode() const

References KisDocument::fileBatchMode(), and m_document.

◆ convert()

KisImportExportManager::ConversionResult KisImportExportManager::convert ( KisImportExportManager::Direction direction,
const QString & location,
const QString & realLocation,
const QString & mimeType,
bool showWarnings,
KisPropertiesConfigurationSP exportConfiguration,
bool isAsync,
bool isAdvancedExporting = false )
private

Fetching a filter from the registry is a really expensive operation, because it blocks all the threads. Cache the filter if possible.

Definition at line 320 of file KisImportExportManager.cpp.

321{
322 // export configuration is supported for export only
323 KIS_SAFE_ASSERT_RECOVER_NOOP(direction == Export || !bool(exportConfiguration));
324
325 QString typeName = mimeType;
326 if (typeName.isEmpty()) {
327 typeName = KisMimeDatabase::mimeTypeForFile(location, direction == KisImportExportManager::Export ? false : true);
328 }
329
331
336 if (direction == KisImportExportManager::Export &&
337 d->cachedExportFilter &&
338 d->cachedExportFilterMimeType == typeName) {
339
340 filter = d->cachedExportFilter;
341 } else {
342
343 filter = toQShared(filterForMimeType(typeName, direction));
344
345 if (direction == Export) {
346 d->cachedExportFilter = filter;
347 d->cachedExportFilterMimeType = typeName;
348 }
349 }
350
351 if (!filter) {
353 }
354
355 filter->setFilename(location);
356 filter->setRealFilename(realLocation);
357 filter->setBatchMode(batchMode());
358 filter->setMimeType(typeName);
359
360 if (direction == Import) {
362 filter->setImportUserFeedBackInterface(new SynchronousUserFeedbackInterface(kisMain, batchMode()));
363 }
364
365 if (!d->updater.isNull()) {
366 // WARNING: The updater is not guaranteed to be persistent! If you ever want
367 // to add progress reporting to "Save also as .kra", make sure you create
368 // a separate KoProgressUpdater for that!
369
370 // WARNING2: the failsafe completion of the updater happens in the destructor
371 // the filter.
372
373 filter->setUpdater(d->updater);
374 }
375
376 QByteArray from, to;
377 if (direction == Export) {
379 to = typeName.toLatin1();
380 }
381 else {
382 from = typeName.toLatin1();
384 }
385
387 direction == Import || direction == Export,
389
390 ConversionResult result = KisImportExportErrorCode(ImportExportCodes::OK);
391 if (direction == Import) {
392
393 KisUsageLogger::log(QString("Importing %1 to %2. Location: %3. Real location: %4. Batchmode: %5")
394 .arg(QString::fromLatin1(from), QString::fromLatin1(to), location,
395 realLocation, QString::number(batchMode())));
396
397 // async importing is not yet supported!
399
400 // FIXME: Dmitry says "this progress reporting code never worked. Initial idea was to implement it his way, but I stopped and didn't finish it"
401 if (0 && !batchMode()) {
402 KisAsyncActionFeedback f(i18n("Opening document..."), 0);
403 result = f.runAction(std::bind(&KisImportExportManager::doImport, this, location, filter));
404 } else {
405 result = doImport(location, filter);
406 }
407 if (result.status().isOk()) {
408 KisImageSP image = m_document->image().toStrongRef();
409 if (image) {
410 KIS_SAFE_ASSERT_RECOVER(image->colorSpace() != nullptr && image->colorSpace()->profile() != nullptr)
411 {
412 qWarning() << "Loaded a profile-less file without a fallback. Rejecting image "
413 "opening";
415 }
416 KisUsageLogger::log(QString("Loaded image from %1. Size: %2 * %3 pixels, %4 dpi. Color "
417 "model: %6 %5 (%7). Layers: %8")
418 .arg(QString::fromLatin1(from), QString::number(image->width()),
419 QString::number(image->height()), QString::number(image->xRes()),
420 image->colorSpace()->colorModelId().name(),
421 image->colorSpace()->colorDepthId().name(),
422 image->colorSpace()->profile()->name(),
423 QString::number(image->nlayers())));
424 } else {
425 qWarning() << "The filter returned OK, but there is no image";
426 }
427
428 }
429 else {
430 KisUsageLogger::log(QString("Failed to load image from %1").arg(QString::fromLatin1(from)));
431 }
432
433 }
434 else /* if (direction == Export) */ {
435 if (!exportConfiguration) {
436 exportConfiguration = filter->lastSavedConfiguration(from, to);
437 }
438
439 if (exportConfiguration) {
440 fillStaticExportConfigurationProperties(exportConfiguration);
441 }
442
443 bool alsoAsKra = false;
444 bool askUser = askUserAboutExportConfiguration(filter, exportConfiguration,
445 from, to,
446 batchMode(), showWarnings,
447 &alsoAsKra, isAdvancedExporting);
448
449
450 if (!batchMode() && !askUser) {
452 }
453
455 QString(
456 "Converting from %1 to %2. Location: %3. Real location: %4. Batchmode: %5. Configuration: %6")
457 .arg(QString::fromLatin1(from), QString::fromLatin1(to), location, realLocation,
458 QString::number(batchMode()),
459 (exportConfiguration ? exportConfiguration->toXML() : "none")));
460
461 const QString alsoAsKraLocation = alsoAsKra ? getAlsoAsKraLocation(location) : QString();
462 if (isAsync) {
463 result = QtConcurrent::run(std::bind(&KisImportExportManager::doExport, this, location, filter,
464 exportConfiguration, alsoAsKraLocation));
465
466 // we should explicitly report that the exporting has been initiated
467 result.setStatus(ImportExportCodes::OK);
468
469 } else if (!batchMode()) {
470 KisAsyncActionFeedback f(i18n("Saving document..."), 0);
471 result = f.runAction(std::bind(&KisImportExportManager::doExport, this, location, filter,
472 exportConfiguration, alsoAsKraLocation));
473 } else {
474 result = doExport(location, filter, exportConfiguration, alsoAsKraLocation);
475 }
476
477 if (exportConfiguration && !batchMode()) {
478 KisConfig(false).setExportConfiguration(typeName, exportConfiguration);
479 }
480 }
481 return result;
482}
void setExportConfiguration(const QString &filterId, KisPropertiesConfigurationSP properties) const
const KoColorSpace * colorSpace() const
double xRes() const
qint32 nlayers() const
KisImportExportErrorCode doExport(const QString &location, QSharedPointer< KisImportExportFilter > filter, KisPropertiesConfigurationSP exportConfiguration, const QString alsoAsKraLocation)
QString getAlsoAsKraLocation(const QString location) const
static KisImportExportFilter * filterForMimeType(const QString &mimetype, Direction direction)
filterForMimeType loads the relevant import/export plugin and returns it. The caller is responsible f...
bool askUserAboutExportConfiguration(QSharedPointer< KisImportExportFilter > filter, KisPropertiesConfigurationSP exportConfiguration, const QByteArray &from, const QByteArray &to, bool batchMode, const bool showWarnings, bool *alsoAsKra, bool isAdvancedExporting=false)
static void fillStaticExportConfigurationProperties(KisPropertiesConfigurationSP exportConfiguration, KisImageSP image)
KisImportExportErrorCode doImport(const QString &location, QSharedPointer< KisImportExportFilter > filter)
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
static void log(const QString &message)
Logs with date/time.
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
QString name() const
Definition KoID.cpp:68
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:85
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
QSharedPointer< T > toQShared(T *ptr)

References askUserAboutExportConfiguration(), batchMode(), ImportExportCodes::Cancelled, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KisImage::colorSpace(), KisPart::currentMainwindow(), d, doExport(), doImport(), Export, ImportExportCodes::FileFormatNotSupported, fillStaticExportConfigurationProperties(), filterForMimeType(), getAlsoAsKraLocation(), KisImage::height(), KisDocument::image, Import, KisPart::instance(), ImportExportCodes::InternalError, KisImportExportErrorCode::isOk(), KIS_ASSERT_RECOVER_RETURN_VALUE, KIS_SAFE_ASSERT_RECOVER, KIS_SAFE_ASSERT_RECOVER_NOOP, KisUsageLogger::log(), m_document, KisMimeDatabase::mimeTypeForFile(), KoID::name(), KoColorProfile::name, KisDocument::nativeFormatMimeType(), KisImage::nlayers(), ImportExportCodes::OK, KoColorSpace::profile(), KisConfig::setExportConfiguration(), KisImportExportManager::ConversionResult::setStatus(), KisImportExportManager::ConversionResult::status(), toQShared(), KisImage::width(), and KisImage::xRes().

◆ doExport()

KisImportExportErrorCode KisImportExportManager::doExport ( const QString & location,
QSharedPointer< KisImportExportFilter > filter,
KisPropertiesConfigurationSP exportConfiguration,
const QString alsoAsKraLocation )
private

Definition at line 753 of file KisImportExportManager.cpp.

757{
759 doExportImpl(location, filter, exportConfiguration);
760
761 if (!alsoAsKraLocation.isNull() && status.isOk()) {
762 QByteArray mime = m_document->nativeFormatMimeType();
764 filterForMimeType(QString::fromLatin1(mime), Export));
765
767
768 if (filter) {
769 filter->setFilename(alsoAsKraLocation);
770
771 KisPropertiesConfigurationSP kraExportConfiguration =
772 filter->lastSavedConfiguration(mime, mime);
773
774 status = doExportImpl(alsoAsKraLocation, filter, kraExportConfiguration);
775 } else {
777 }
778 }
779
780 return status;
781}
KisImportExportErrorCode doExportImpl(const QString &location, QSharedPointer< KisImportExportFilter > filter, KisPropertiesConfigurationSP exportConfiguration)

References doExportImpl(), Export, ImportExportCodes::FileFormatIncorrect, filterForMimeType(), KisImportExportErrorCode::isOk(), KIS_SAFE_ASSERT_RECOVER_NOOP, m_document, and KisDocument::nativeFormatMimeType().

◆ doExportImpl()

KisImportExportErrorCode KisImportExportManager::doExportImpl ( const QString & location,
QSharedPointer< KisImportExportFilter > filter,
KisPropertiesConfigurationSP exportConfiguration )
private

Definition at line 814 of file KisImportExportManager.cpp.

815{
816#ifdef USE_QSAVEFILE
817 QSaveFile file(location);
818 file.setDirectWriteFallback(true);
819 if (filter->supportsIO() && !file.open(QFile::WriteOnly)) {
820#else
821 QFileInfo fi(location);
822 QTemporaryFile file(QDir::tempPath() + "/.XXXXXX.kra");
823 if (filter->supportsIO() && !file.open()) {
824#endif
825 KisImportExportErrorCannotWrite result(getFileOpenError(file));
826#ifdef USE_QSAVEFILE
827 file.cancelWriting();
828#endif
829 return result;
830 }
831
832 KisImportExportErrorCode status = filter->convert(m_document, &file, exportConfiguration);
833
834 if (filter->supportsIO()) {
835 if (!status.isOk()) {
836#ifdef USE_QSAVEFILE
837 file.cancelWriting();
838#endif
839 } else {
840#ifdef USE_QSAVEFILE
841 if (!file.commit()) {
842 qWarning() << "Could not commit QSaveFile";
843 status = KisImportExportErrorCannotWrite(file.error());
844 }
845#elif defined(Q_OS_ANDROID)
846 // The Android file system is bananas, so it needs special handling.
847
848 // If the temporary file is still open, ensure it's fully written.
849 // If it got closed, open it again so that we can read from it.
850 if(file.isOpen()) {
851 if (!file.flush()) {
853 }
854 } else if (!file.open()) {
855 return KisImportExportErrorCannotWrite(getFileOpenError(file));
856 }
857
858 // Grab the size we're expecting to write for later verification.
859 qint64 expectedSize = file.size();
860 if (expectedSize < 0 || !file.seek(0)) {
862 }
863
864 // Open the target file. We have to explicitly tell the file to
865 // truncate itself because unlike on every other system it doesn't
866 // do that on its own when opening a file for writing, it just
867 // leaves the old content laying around and you start overwriting
868 // it, potentially leaving old garbage at the end of the file.
869 QFile target(location);
870 if (!target.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
871 return KisImportExportErrorCannotWrite(getFileOpenError(target));
872 }
873
874 // QFile::copy also doesn't work, so we gotta do it manually by
875 // alternately reading and writing BUFSIZ-sized chunks.
876 QByteArray buf;
877 buf.resize(BUFSIZ);
878 qint64 totalWritten = 0;
879 while (true) {
880 qint64 read = file.read(buf.data(), BUFSIZ);
881 if (read < 0) {
882 // Read error.
884 } else if (read == 0) {
885 // End of file.
886 break;
887 } else {
888 // Successful read, try to write it.
889 qint64 written = target.write(buf.constData(), read);
890 if (written < 0) {
891 // Write error.
893 }
894 // We may not have written as much as we read, but we handle
895 // that at the end.
896 totalWritten += written;
897 }
898 }
899
900 // Finish up and make sure what we wrote is out to storage.
901 file.close();
902 if (!target.flush()) {
904 }
905 target.close();
906
907 // Now check if we actually wrote as much as we wanted to. If not,
908 // raise an error. There's not much we can do about it though, since
909 // we already truncated the original file at this point and don't
910 // have permissions to create backup files in the sandbox.
911 if (totalWritten != expectedSize) {
912 return KisImportExportErrorCannotWrite(QFileDevice::CopyError);
913 }
914#else
915 file.flush();
916 file.close();
917 QFile target(location);
918 if (target.exists()) {
919 // There should already be a .kra~ backup
920 target.remove();
921 }
922 if (!file.copy(location)) {
923 file.setAutoRemove(false);
925 }
926#endif
927 }
928 }
929
930 if (status.isOk()) {
931 // Do some minimal verification
932 QString verificationResult = filter->verify(location);
933 if (!verificationResult.isEmpty()) {
935 m_document->setErrorMessage(verificationResult);
936 }
937 }
938
939 return status;
940
941}
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
void setErrorMessage(const QString &errMsg)

References ImportExportCodes::ErrorWhileWriting, KisImportExportErrorCode::isOk(), m_document, KisDocument::setErrorMessage(), and target().

◆ doImport()

KisImportExportErrorCode KisImportExportManager::doImport ( const QString & location,
QSharedPointer< KisImportExportFilter > filter )
private

Definition at line 733 of file KisImportExportManager.cpp.

734{
735 QFile file(location);
736 if (!file.exists()) {
738 }
739
740 if (filter->supportsIO() && !file.open(QFile::ReadOnly)) {
742 }
743
744 KisImportExportErrorCode status = filter->convert(m_document, &file, KisPropertiesConfigurationSP());
745
746 if (file.isOpen()) {
747 file.close();
748 }
749
750 return status;
751}
KisPinnedSharedPtr< KisPropertiesConfiguration > KisPropertiesConfigurationSP
Definition kis_types.h:278

References ImportExportCodes::FileNotExist, and m_document.

◆ exportDocument()

KisImportExportErrorCode KisImportExportManager::exportDocument ( const QString & location,
const QString & realLocation,
const QByteArray & mimeType,
bool showWarnings = true,
KisPropertiesConfigurationSP exportConfiguration = 0,
bool isAdvancedExporting = false )

Exports the given file/document to the specified URL/mimetype.

If mimeType is empty, then the closest matching Calligra part is searched and when the method returns mimeType contains this mimetype. Oh, well, export is a C++ keyword ;)

Definition at line 167 of file KisImportExportManager.cpp.

168{
169 ConversionResult result = convert(Export, location, realLocation, mimeType, showWarnings, exportConfiguration, false, isAdvancedExporting);
171
172 return result.status();
173}
ConversionResult convert(Direction direction, const QString &location, const QString &realLocation, const QString &mimeType, bool showWarnings, KisPropertiesConfigurationSP exportConfiguration, bool isAsync, bool isAdvancedExporting=false)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References convert(), Export, ImportExportCodes::InternalError, KisImportExportManager::ConversionResult::isAsync(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and KisImportExportManager::ConversionResult::status().

◆ exportDocumentAsync()

QFuture< KisImportExportErrorCode > KisImportExportManager::exportDocumentAsync ( const QString & location,
const QString & realLocation,
const QByteArray & mimeType,
KisImportExportErrorCode & status,
bool showWarnings = true,
KisPropertiesConfigurationSP exportConfiguration = 0,
bool isAdvancedExporting = false )

Definition at line 175 of file KisImportExportManager.cpp.

177{
178 ConversionResult result = convert(Export, location, realLocation, mimeType, showWarnings, exportConfiguration, true, isAdvancedExporting);
179 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(result.isAsync() ||
180 !result.status().isOk(), QFuture<KisImportExportErrorCode>());
181
182 status = result.status();
183 return result.futureStatus();
184}

References convert(), Export, KisImportExportManager::ConversionResult::futureStatus(), KisImportExportManager::ConversionResult::isAsync(), KisImportExportErrorCode::isOk(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and KisImportExportManager::ConversionResult::status().

◆ fillStaticExportConfigurationProperties() [1/2]

void KisImportExportManager::fillStaticExportConfigurationProperties ( KisPropertiesConfigurationSP exportConfiguration)
private

Definition at line 518 of file KisImportExportManager.cpp.

519{
520 return fillStaticExportConfigurationProperties(exportConfiguration, m_document->image());
521}

References fillStaticExportConfigurationProperties(), KisDocument::image, and m_document.

◆ fillStaticExportConfigurationProperties() [2/2]

void KisImportExportManager::fillStaticExportConfigurationProperties ( KisPropertiesConfigurationSP exportConfiguration,
KisImageSP image )
static

Fill necessary information for the export filter into the properties, e.g. if the image has transparency or has sRGB profile.

Definition at line 484 of file KisImportExportManager.cpp.

485{
486 KisPaintDeviceSP dev = image->projection();
487 const KoColorSpace* cs = dev->colorSpace();
488 const bool isThereAlpha =
490
491 exportConfiguration->setProperty(KisImportExportFilter::ImageContainsTransparencyTag, isThereAlpha);
492 exportConfiguration->setProperty(KisImportExportFilter::ColorModelIDTag, cs->colorModelId().id());
493 exportConfiguration->setProperty(KisImportExportFilter::ColorDepthIDTag, cs->colorDepthId().id());
494
495 const bool sRGB =
496 (cs->profile()->name().contains(QLatin1String("srgb"), Qt::CaseInsensitive) &&
497 !cs->profile()->name().contains(QLatin1String("g10")));
498 exportConfiguration->setProperty(KisImportExportFilter::sRGBTag, sRGB);
499
500 ColorPrimaries primaries = cs->profile()->getColorPrimaries();
501 if (primaries >= PRIMARIES_ADOBE_RGB_1998) {
502 primaries = PRIMARIES_UNSPECIFIED;
503 }
504 TransferCharacteristics transferFunction =
506 if (transferFunction >= TRC_GAMMA_1_8) {
507 transferFunction = TRC_UNSPECIFIED;
508 }
509 exportConfiguration->setProperty(KisImportExportFilter::CICPPrimariesTag,
510 static_cast<int>(primaries));
511 exportConfiguration->setProperty(
513 static_cast<int>(transferFunction));
514 exportConfiguration->setProperty(KisImportExportFilter::HDRTag, cs->hasHighDynamicRange());
515}
ColorPrimaries
The colorPrimaries enum Enum of colorants, follows ITU H.273 for values 0 to 255, and has extra known...
@ PRIMARIES_UNSPECIFIED
@ PRIMARIES_ADOBE_RGB_1998
TransferCharacteristics
The transferCharacteristics enum Enum of transfer characteristics, follows ITU H.273 for values 0 to ...
KisPaintDeviceSP projection() const
static const QString ColorDepthIDTag
static const QString ColorModelIDTag
static const QString CICPTransferCharacteristicsTag
static const QString CICPPrimariesTag
static const QString ImageContainsTransparencyTag
static const QString sRGBTag
static const QString HDRTag
const KoColorSpace * colorSpace() const
static bool checkDeviceHasTransparency(KisPaintDeviceSP dev)
virtual bool hasHighDynamicRange() const =0
QString id() const
Definition KoID.cpp:63
virtual ColorPrimaries getColorPrimaries() const
getColorPrimaries
virtual TransferCharacteristics getTransferCharacteristics() const
getTransferCharacteristics This function should be subclassed at some point so we can get the value f...

References KisPainter::checkDeviceHasTransparency(), KisImportExportFilter::CICPPrimariesTag, KisImportExportFilter::CICPTransferCharacteristicsTag, KoColorSpace::colorDepthId(), KisImportExportFilter::ColorDepthIDTag, KoColorSpace::colorModelId(), KisImportExportFilter::ColorModelIDTag, KisPaintDevice::colorSpace(), KoColorProfile::getColorPrimaries(), KoColorProfile::getTransferCharacteristics(), KoColorSpace::hasHighDynamicRange(), KisImportExportFilter::HDRTag, KoID::id(), KisImportExportFilter::ImageContainsTransparencyTag, KoColorProfile::name, PRIMARIES_ADOBE_RGB_1998, PRIMARIES_UNSPECIFIED, KoColorSpace::profile(), KisImage::projection(), KisImportExportFilter::sRGBTag, TRC_GAMMA_1_8, and TRC_UNSPECIFIED.

◆ filterForMimeType()

KisImportExportFilter * KisImportExportManager::filterForMimeType ( const QString & mimetype,
KisImportExportManager::Direction direction )
static

filterForMimeType loads the relevant import/export plugin and returns it. The caller is responsible for deleting it!

Parameters
mimetypethe mimetype we want to import/export. If there's more than one plugin, the one with the highest weight as defined in the json description will be taken
directionimport or export
Returns
a pointer to the filter plugin or 0 if none could be found

Definition at line 227 of file KisImportExportManager.cpp.

228{
229 int weight = -1;
230 KisImportExportFilter *filter = 0;
231 QList<KoJsonTrader::Plugin>list = KoJsonTrader::instance()->query("Krita/FileFilter", "");
232
233 Q_FOREACH(const KoJsonTrader::Plugin &loader, list) {
234 QJsonObject json = loader.metaData().value("MetaData").toObject();
235 QString directionKey = direction == Export ? "X-KDE-Export" : "X-KDE-Import";
236
237 if (json.value(directionKey).toString().split(",", Qt::SkipEmptyParts).contains(mimetype)) {
238
239 KPluginFactory *factory = qobject_cast<KPluginFactory *>(loader.instance());
240
241 if (!factory) {
242 warnUI << loader.errorString();
243 continue;
244 }
245
246 QObject* obj = factory->create<KisImportExportFilter>(0);
247 if (!obj || !obj->inherits("KisImportExportFilter")) {
248 delete obj;
249 continue;
250 }
251
252 KisImportExportFilter *f = qobject_cast<KisImportExportFilter*>(obj);
253 if (!f) {
254 delete obj;
255 continue;
256 }
257
258 KIS_ASSERT_RECOVER_NOOP(json.value("X-KDE-Weight").isDouble());
259
260 int w = json.value("X-KDE-Weight").toInt();
261
262 if (w > weight) {
263 delete filter;
264 filter = f;
265 f->setObjectName(loader.fileName());
266 weight = w;
267 }
268 }
269 }
270
271 if (filter) {
272 filter->setMimeType(mimetype);
273 }
274 return filter;
275}
The base class for import and export filters.
void setMimeType(const QString &mime)
static KoJsonTrader * instance()
QList< Plugin > query(const QString &servicetype, const QString &mimetype)
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
#define warnUI
Definition kis_debug.h:94
QObject * instance() const
QString fileName() const
QJsonObject metaData() const
QString errorString() const

References KoJsonTrader::Plugin::errorString(), Export, KoJsonTrader::Plugin::fileName(), KoJsonTrader::instance(), KoJsonTrader::Plugin::instance(), KIS_ASSERT_RECOVER_NOOP, KoJsonTrader::Plugin::metaData(), KoJsonTrader::query(), KisImportExportFilter::setMimeType(), and warnUI.

◆ getAlsoAsKraLocation()

QString KisImportExportManager::getAlsoAsKraLocation ( const QString location) const
private

Definition at line 943 of file KisImportExportManager.cpp.

944{
945#ifdef Q_OS_ANDROID
946 return getUriForAdditionalFile(location, nullptr);
947#else
948 return location + ".kra";
949#endif
950}
static QString getUriForAdditionalFile(const QString &defaultUri, QWidget *parent)

References getUriForAdditionalFile().

◆ getUriForAdditionalFile()

QString KisImportExportManager::getUriForAdditionalFile ( const QString & defaultUri,
QWidget * parent )
static

Definition at line 308 of file KisImportExportManager.cpp.

309{
310 KoFileDialog dialog(parent, KoFileDialog::SaveFile, "Save Kra");
311
312 KIS_SAFE_ASSERT_RECOVER_NOOP(!defaultUri.isEmpty());
313
314 dialog.setDirectoryUrl(QUrl(defaultUri));
315 dialog.setMimeTypeFilters(QStringList("application/x-krita"));
316
317 return dialog.filename();
318}
QList< QString > QStringList

References KIS_SAFE_ASSERT_RECOVER_NOOP, and KoFileDialog::SaveFile.

◆ importDocument()

KisImportExportErrorCode KisImportExportManager::importDocument ( const QString & location,
const QString & mimeType )

Imports the specified document and returns the resultant filename (most likely some file in /tmp). path can be either a URL or a filename. documentMimeType gives importDocument a hint about what type the document may be. It can be left empty.

Returns
status signals the success/error of the conversion. If the QString which is returned isEmpty() and the status is OK, then we imported the file directly into the document.

Definition at line 159 of file KisImportExportManager.cpp.

160{
161 ConversionResult result = convert(Import, location, location, mimeType, false, 0, false);
163
164 return result.status();
165}

References convert(), Import, ImportExportCodes::InternalError, KisImportExportManager::ConversionResult::isAsync(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and KisImportExportManager::ConversionResult::status().

◆ operator=()

KisImportExportManager & KisImportExportManager::operator= ( const KisImportExportManager & rhs)
private

◆ setUpdater()

void KisImportExportManager::setUpdater ( KoUpdaterPtr updater)

Definition at line 282 of file KisImportExportManager.cpp.

283{
284 d->updater = updater;
285}

References d, and updater.

◆ supportedMimeTypes()

QStringList KisImportExportManager::supportedMimeTypes ( Direction direction)
static

Suitable for passing to KoFileDialog::setMimeTypeFilters. The default mime gets set by the "users" of this method, as we do not have enough information here. Optionally, extraNativeMimeTypes are added after the native mimetype.

Definition at line 188 of file KisImportExportManager.cpp.

189{
190 // Find the right mimetype by the extension
191 QSet<QString> mimeTypes;
192 // mimeTypes << KisDocument::nativeFormatMimeType() << "application/x-krita-paintoppreset" << "image/openraster";
193
194 if (direction == KisImportExportManager::Import) {
195 if (m_importMimeTypes.isEmpty()) {
196 QList<KoJsonTrader::Plugin> list = KoJsonTrader::instance()->query("Krita/FileFilter", "");
197 Q_FOREACH(const KoJsonTrader::Plugin &loader, list) {
198 QJsonObject json = loader.metaData().value("MetaData").toObject();
199 Q_FOREACH(const QString &mimetype, json.value("X-KDE-Import").toString().split(",", Qt::SkipEmptyParts)) {
200
201 //qDebug() << "Adding import mimetype" << mimetype << KisMimeDatabase::descriptionForMimeType(mimetype) << "from plugin" << loader;
202 mimeTypes << mimetype;
203 }
204 }
205 m_importMimeTypes = QList<QString>(mimeTypes.begin(), mimeTypes.end());
206 }
207 return m_importMimeTypes;
208 }
209 else if (direction == KisImportExportManager::Export) {
210 if (m_exportMimeTypes.isEmpty()) {
211 QList<KoJsonTrader::Plugin> list = KoJsonTrader::instance()->query("Krita/FileFilter", "");
212 Q_FOREACH(const KoJsonTrader::Plugin &loader, list) {
213 QJsonObject json = loader.metaData().value("MetaData").toObject();
214 Q_FOREACH(const QString &mimetype, json.value("X-KDE-Export").toString().split(",", Qt::SkipEmptyParts)) {
215
216 //qDebug() << "Adding export mimetype" << mimetype << KisMimeDatabase::descriptionForMimeType(mimetype) << "from plugin" << loader;
217 mimeTypes << mimetype;
218 }
219 }
220 m_exportMimeTypes = QList<QString>(mimeTypes.begin(), mimeTypes.end());
221 }
222 return m_exportMimeTypes;
223 }
224 return QStringList();
225}
static QStringList m_exportMimeTypes
static QStringList m_importMimeTypes
A static cache for the availability checks of filters.

References Export, Import, KoJsonTrader::instance(), m_exportMimeTypes, m_importMimeTypes, KoJsonTrader::Plugin::metaData(), and KoJsonTrader::query().

Member Data Documentation

◆ cachedExportFilter

QSharedPointer<KisImportExportFilter> KisImportExportManager::cachedExportFilter

Definition at line 102 of file KisImportExportManager.cpp.

◆ cachedExportFilterMimeType

QString KisImportExportManager::cachedExportFilterMimeType

Definition at line 101 of file KisImportExportManager.cpp.

◆ d

Private* const KisImportExportManager::d
private

Definition at line 146 of file KisImportExportManager.h.

◆ m_document

KisDocument* KisImportExportManager::m_document
private

Definition at line 139 of file KisImportExportManager.h.

◆ m_exportMimeTypes

QStringList KisImportExportManager::m_exportMimeTypes
staticprivate

Definition at line 143 of file KisImportExportManager.h.

◆ m_importMimeTypes

QStringList KisImportExportManager::m_importMimeTypes
staticprivate

A static cache for the availability checks of filters.

Definition at line 142 of file KisImportExportManager.h.

◆ updater

KoUpdaterPtr KisImportExportManager::updater

Definition at line 99 of file KisImportExportManager.cpp.


The documentation for this class was generated from the following files: