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 95 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 147 of file KisImportExportManager.cpp.

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

◆ ~KisImportExportManager()

KisImportExportManager::~KisImportExportManager ( )
override

Definition at line 153 of file KisImportExportManager.cpp.

154{
155 delete d;
156}

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 286 of file KisImportExportManager.cpp.

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

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 522 of file KisImportExportManager.cpp.

531{
532
533 // prevents the animation renderer from running this code
534
535
536 const QString mimeUserDescription = KisMimeDatabase::descriptionForMimeType(to);
537
538 QStringList warnings;
539 QStringList errors;
540
541 {
542 KisPreExportChecker checker;
543 checker.check(m_document->image(), filter->exportChecks());
544
545 warnings = checker.warnings();
546 errors = checker.errors();
547 }
548
549 KisConfigWidget *wdg = 0;
550
551 if (QThread::currentThread() == qApp->thread()) {
552 wdg = filter->createConfigurationWidget(0, from, to);
553
555 if (wdg && kisMain) {
556 KisViewManager *manager = kisMain->viewManager();
557 wdg->setView(manager);
558 }
559 }
560
561 // Extra checks that cannot be done by the checker, because the checker only has access to the image.
562 if (!m_document->assistants().isEmpty() && to != m_document->nativeFormatMimeType()) {
563 warnings.append(i18nc("image conversion warning", "The image contains <b>assistants</b>. The assistants will not be saved."));
564 }
566 warnings.append(i18nc("image conversion warning", "The image contains <b>reference images</b>. The reference images will not be saved."));
567 }
568 if (m_document->guidesConfig().hasGuides() && !filter->exportSupportsGuides()) {
569 warnings.append(i18nc("image conversion warning", "The image contains <b>guides</b>. The guides will not be saved."));
570 }
572 warnings.append(i18nc("image conversion warning", "The image contains a <b>custom grid configuration</b>. The configuration will not be saved."));
573 }
574
575 bool shouldFlattenTheImageBeforeScaling = false;
576
577 if (isAdvancedExporting) {
578 QMap<QString, KisExportCheckBase *> exportChecks = filter->exportChecks();
579
580 const bool filterSupportsMultilayerExport =
581 exportChecks.contains("MultiLayerCheck") &&
582 exportChecks["MultiLayerCheck"]->checkNeeded(m_document->image()) &&
583 exportChecks["MultiLayerCheck"]->check(m_document->image()) == KisExportCheckBase::SUPPORTED;
584
585 if (!filterSupportsMultilayerExport) {
586 shouldFlattenTheImageBeforeScaling = true;
587 } else {
588 if (KisLayerUtils::findNodeByType<KisAdjustmentLayer>(m_document->image()->root())) {
589 shouldFlattenTheImageBeforeScaling = true;
590 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."));
591 }
592 if (KisLayerUtils::findNodeByType<KisFilterMask>(m_document->image()->root())) {
593 shouldFlattenTheImageBeforeScaling = true;
594 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."));
595 }
596 bool hasLayerStyles =
598 [] (KisNodeSP node) {
599 KisLayer *layer = dynamic_cast<KisLayer*>(node.data());
600 return layer && layer->layerStyle();
601 });
602
603 if (hasLayerStyles) {
604 shouldFlattenTheImageBeforeScaling = true;
605 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."));
606 }
607 }
608 }
609
610 if (!batchMode && !errors.isEmpty()) {
611 QString error = "<html><body><p><b>"
612 + i18n("Error: cannot save this image as a %1.", mimeUserDescription)
613 + "</b> " + i18n("Reasons:") + "</p>"
614 + "<p/><ul>";
615 Q_FOREACH(const QString &w, errors) {
616 error += "\n<li>" + w + "</li>";
617 }
618
619 error += "</ul>";
620
621 QMessageBox::critical(KisPart::instance()->currentMainwindow(), i18nc("@title:window", "Krita: Export Error"), error);
622 return false;
623 }
624
625 if (!batchMode && (wdg || !warnings.isEmpty() || isAdvancedExporting)) {
626 QWidget *page = new QWidget();
627 QVBoxLayout *layout = new QVBoxLayout(page);
628
629 if (showWarnings && !warnings.isEmpty()) {
630 QHBoxLayout *hLayout = new QHBoxLayout();
631
632 QLabel *labelWarning = new QLabel();
633 labelWarning->setPixmap(KisIconUtils::loadIcon("dialog-warning").pixmap(48, 48));
634 hLayout->addWidget(labelWarning);
635
636 KisPopupButton *bn = new KisPopupButton(0);
637
638 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));
639 bn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
640
641 hLayout->addWidget(bn);
642
643 layout->addLayout(hLayout);
644
645 QTextBrowser *browser = new QTextBrowser();
646 browser->setMinimumWidth(bn->width());
647 bn->setPopupWidget(browser);
648
649 QString warning = "<html><body><p><b>"
650 + i18n("You will lose information when saving this image as a %1.", mimeUserDescription);
651
652 if (warnings.size() == 1) {
653 warning += "</b> " + i18n("Reason:") + "</p>";
654 }
655 else {
656 warning += "</b> " + i18n("Reasons:") + "</p>";
657 }
658 warning += "<p/><ul>";
659
660 Q_FOREACH(const QString &w, warnings) {
661 warning += "\n<li>" + w + "</li>";
662 }
663
664 warning += "</ul>";
665 browser->setHtml(warning);
666 }
667
668 QTabWidget *box = new QTabWidget;
669 if (wdg) {
670 wdg->setConfiguration(exportConfiguration);
671 box->addTab(wdg,i18n("Options"));
672 }
673
674 WdgImageSize *wdgImageSize = nullptr;
675
676 if (isAdvancedExporting) {
677 wdgImageSize = new WdgImageSize(box, m_document->image()->width(), m_document->image()->height(), m_document->image()->yRes());
678
679 box->addTab(wdgImageSize,i18n("Resize"));
680 }
681 layout->addWidget(box);
682
683 QCheckBox *chkAlsoAsKra = 0;
684 if (showWarnings && !warnings.isEmpty()) {
685 chkAlsoAsKra = new QCheckBox(i18n("Also save your image as a Krita file."));
686 chkAlsoAsKra->setChecked(KisConfig(true).readEntry<bool>("AlsoSaveAsKra", false));
687 layout->addWidget(chkAlsoAsKra);
688 }
689
690 KoDialog dlg(qApp->activeWindow());
691 dlg.setMainWidget(page);
692 page->setParent(&dlg);
693 dlg.setButtons(KoDialog::Ok | KoDialog::Cancel);
694 dlg.setWindowTitle(mimeUserDescription);
695
696 if (showWarnings || wdg || isAdvancedExporting) {
697 if (!dlg.exec()) {
698 return false;
699 }
700 }
701
702 *alsoAsKra = false;
703 if (chkAlsoAsKra) {
704 KisConfig(false).writeEntry<bool>("AlsoSaveAsKra", chkAlsoAsKra->isChecked());
705 *alsoAsKra = chkAlsoAsKra->isChecked();
706 }
707
708 KIS_SAFE_ASSERT_RECOVER_NOOP(bool(isAdvancedExporting) == bool(wdgImageSize));
709
710 if (isAdvancedExporting && wdgImageSize) {
711 if (shouldFlattenTheImageBeforeScaling) {
714 }
715
716 const QSize desiredSize(wdgImageSize->desiredWidth(), wdgImageSize->desiredHeight());
717 double res = wdgImageSize->desiredResolution();
718 m_document->savingImage()->scaleImage(desiredSize,res,res,wdgImageSize->filterType());
722 }
723
724 if (wdg) {
725 *exportConfiguration = *wdg->configuration();
726 }
727 }
728
729 return true;
730}
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:779
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
Definition kis_image.cc:961
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:483
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 276 of file KisImportExportManager.cpp.

277{
278 return m_document->fileBatchMode();
279}
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 319 of file KisImportExportManager.cpp.

320{
321 // export configuration is supported for export only
322 KIS_SAFE_ASSERT_RECOVER_NOOP(direction == Export || !bool(exportConfiguration));
323
324 QString typeName = mimeType;
325 if (typeName.isEmpty()) {
326 typeName = KisMimeDatabase::mimeTypeForFile(location, direction == KisImportExportManager::Export ? false : true);
327 }
328
330
335 if (direction == KisImportExportManager::Export &&
336 d->cachedExportFilter &&
337 d->cachedExportFilterMimeType == typeName) {
338
339 filter = d->cachedExportFilter;
340 } else {
341
342 filter = toQShared(filterForMimeType(typeName, direction));
343
344 if (direction == Export) {
345 d->cachedExportFilter = filter;
346 d->cachedExportFilterMimeType = typeName;
347 }
348 }
349
350 if (!filter) {
352 }
353
354 filter->setFilename(location);
355 filter->setRealFilename(realLocation);
356 filter->setBatchMode(batchMode());
357 filter->setMimeType(typeName);
358
359 if (direction == Import) {
361 filter->setImportUserFeedBackInterface(new SynchronousUserFeedbackInterface(kisMain, batchMode()));
362 }
363
364 if (!d->updater.isNull()) {
365 // WARNING: The updater is not guaranteed to be persistent! If you ever want
366 // to add progress reporting to "Save also as .kra", make sure you create
367 // a separate KoProgressUpdater for that!
368
369 // WARNING2: the failsafe completion of the updater happens in the destructor
370 // the filter.
371
372 filter->setUpdater(d->updater);
373 }
374
375 QByteArray from, to;
376 if (direction == Export) {
378 to = typeName.toLatin1();
379 }
380 else {
381 from = typeName.toLatin1();
383 }
384
386 direction == Import || direction == Export,
388
389 ConversionResult result = KisImportExportErrorCode(ImportExportCodes::OK);
390 if (direction == Import) {
391
392 KisUsageLogger::log(QString("Importing %1 to %2. Location: %3. Real location: %4. Batchmode: %5")
393 .arg(QString::fromLatin1(from), QString::fromLatin1(to), location,
394 realLocation, QString::number(batchMode())));
395
396 // async importing is not yet supported!
398
399 // 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"
400 if (0 && !batchMode()) {
401 KisAsyncActionFeedback f(i18n("Opening document..."), 0);
402 result = f.runAction(std::bind(&KisImportExportManager::doImport, this, location, filter));
403 } else {
404 result = doImport(location, filter);
405 }
406 if (result.status().isOk()) {
407 KisImageSP image = m_document->image().toStrongRef();
408 if (image) {
409 KIS_SAFE_ASSERT_RECOVER(image->colorSpace() != nullptr && image->colorSpace()->profile() != nullptr)
410 {
411 qWarning() << "Loaded a profile-less file without a fallback. Rejecting image "
412 "opening";
414 }
415 KisUsageLogger::log(QString("Loaded image from %1. Size: %2 * %3 pixels, %4 dpi. Color "
416 "model: %6 %5 (%7). Layers: %8")
417 .arg(QString::fromLatin1(from), QString::number(image->width()),
418 QString::number(image->height()), QString::number(image->xRes()),
419 image->colorSpace()->colorModelId().name(),
420 image->colorSpace()->colorDepthId().name(),
421 image->colorSpace()->profile()->name(),
422 QString::number(image->nlayers())));
423 } else {
424 qWarning() << "The filter returned OK, but there is no image";
425 }
426
427 }
428 else {
429 KisUsageLogger::log(QString("Failed to load image from %1").arg(QString::fromLatin1(from)));
430 }
431
432 }
433 else /* if (direction == Export) */ {
434 if (!exportConfiguration) {
435 exportConfiguration = filter->lastSavedConfiguration(from, to);
436 }
437
438 if (exportConfiguration) {
439 fillStaticExportConfigurationProperties(exportConfiguration);
440 }
441
442 bool alsoAsKra = false;
443 bool askUser = askUserAboutExportConfiguration(filter, exportConfiguration,
444 from, to,
445 batchMode(), showWarnings,
446 &alsoAsKra, isAdvancedExporting);
447
448
449 if (!batchMode() && !askUser) {
451 }
452
454 QString(
455 "Converting from %1 to %2. Location: %3. Real location: %4. Batchmode: %5. Configuration: %6")
456 .arg(QString::fromLatin1(from), QString::fromLatin1(to), location, realLocation,
457 QString::number(batchMode()),
458 (exportConfiguration ? exportConfiguration->toXML() : "none")));
459
460 const QString alsoAsKraLocation = alsoAsKra ? getAlsoAsKraLocation(location) : QString();
461 if (isAsync) {
462 result = QtConcurrent::run(std::bind(&KisImportExportManager::doExport, this, location, filter,
463 exportConfiguration, alsoAsKraLocation));
464
465 // we should explicitly report that the exporting has been initiated
466 result.setStatus(ImportExportCodes::OK);
467
468 } else if (!batchMode()) {
469 KisAsyncActionFeedback f(i18n("Saving document..."), 0);
470 result = f.runAction(std::bind(&KisImportExportManager::doExport, this, location, filter,
471 exportConfiguration, alsoAsKraLocation));
472 } else {
473 result = doExport(location, filter, exportConfiguration, alsoAsKraLocation);
474 }
475
476 if (exportConfiguration && !batchMode()) {
477 KisConfig(false).setExportConfiguration(typeName, exportConfiguration);
478 }
479 }
480 return result;
481}
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 752 of file KisImportExportManager.cpp.

756{
758 doExportImpl(location, filter, exportConfiguration);
759
760 if (!alsoAsKraLocation.isNull() && status.isOk()) {
761 QByteArray mime = m_document->nativeFormatMimeType();
763 filterForMimeType(QString::fromLatin1(mime), Export));
764
766
767 if (filter) {
768 filter->setFilename(alsoAsKraLocation);
769
770 KisPropertiesConfigurationSP kraExportConfiguration =
771 filter->lastSavedConfiguration(mime, mime);
772
773 status = doExportImpl(alsoAsKraLocation, filter, kraExportConfiguration);
774 } else {
776 }
777 }
778
779 return status;
780}
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

On Android Qt's AndroidContentFileEngine::open may be not very accurate with setting a proper error code when requesting file descriptor from JNI and getting a refusal. We should handle this condition gracefully.

Definition at line 794 of file KisImportExportManager.cpp.

795{
796#ifdef USE_QSAVEFILE
797 QSaveFile file(location);
798 file.setDirectWriteFallback(true);
799 if (filter->supportsIO() && !file.open(QFile::WriteOnly)) {
800#else
801 QFileInfo fi(location);
802 QTemporaryFile file(QDir::tempPath() + "/.XXXXXX.kra");
803 if (filter->supportsIO() && !file.open()) {
804#endif
805 QFileDevice::FileError error = file.error();
806 if (file.error() == QFileDevice::NoError) {
813 error = QFileDevice::OpenError;
814 }
816#ifdef USE_QSAVEFILE
817 file.cancelWriting();
818#endif
819 return result;
820 }
821
822 KisImportExportErrorCode status = filter->convert(m_document, &file, exportConfiguration);
823
824 if (filter->supportsIO()) {
825 if (!status.isOk()) {
826#ifdef USE_QSAVEFILE
827 file.cancelWriting();
828#endif
829 } else {
830#ifdef USE_QSAVEFILE
831 if (!file.commit()) {
832 qWarning() << "Could not commit QSaveFile";
833 status = KisImportExportErrorCannotWrite(file.error());
834 }
835#else
836 file.flush();
837 file.close();
838 QFile target(location);
839 if (target.exists()) {
840 // There should already be a .kra~ backup
841 target.remove();
842 }
843 if (!file.copy(location)) {
844 file.setAutoRemove(false);
846 }
847#endif
848 }
849 }
850
851 if (status.isOk()) {
852 // Do some minimal verification
853 QString verificationResult = filter->verify(location);
854 if (!verificationResult.isEmpty()) {
856 m_document->setErrorMessage(verificationResult);
857 }
858 }
859
860 return status;
861
862}
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 732 of file KisImportExportManager.cpp.

733{
734 QFile file(location);
735 if (!file.exists()) {
737 }
738
739 if (filter->supportsIO() && !file.open(QFile::ReadOnly)) {
741 }
742
743 KisImportExportErrorCode status = filter->convert(m_document, &file, KisPropertiesConfigurationSP());
744
745 if (file.isOpen()) {
746 file.close();
747 }
748
749 return status;
750}
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 166 of file KisImportExportManager.cpp.

167{
168 ConversionResult result = convert(Export, location, realLocation, mimeType, showWarnings, exportConfiguration, false, isAdvancedExporting);
170
171 return result.status();
172}
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 174 of file KisImportExportManager.cpp.

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

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 517 of file KisImportExportManager.cpp.

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

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 483 of file KisImportExportManager.cpp.

484{
485 KisPaintDeviceSP dev = image->projection();
486 const KoColorSpace* cs = dev->colorSpace();
487 const bool isThereAlpha =
489
490 exportConfiguration->setProperty(KisImportExportFilter::ImageContainsTransparencyTag, isThereAlpha);
491 exportConfiguration->setProperty(KisImportExportFilter::ColorModelIDTag, cs->colorModelId().id());
492 exportConfiguration->setProperty(KisImportExportFilter::ColorDepthIDTag, cs->colorDepthId().id());
493
494 const bool sRGB =
495 (cs->profile()->name().contains(QLatin1String("srgb"), Qt::CaseInsensitive) &&
496 !cs->profile()->name().contains(QLatin1String("g10")));
497 exportConfiguration->setProperty(KisImportExportFilter::sRGBTag, sRGB);
498
499 ColorPrimaries primaries = cs->profile()->getColorPrimaries();
500 if (primaries >= PRIMARIES_ADOBE_RGB_1998) {
501 primaries = PRIMARIES_UNSPECIFIED;
502 }
503 TransferCharacteristics transferFunction =
505 if (transferFunction >= TRC_GAMMA_1_8) {
506 transferFunction = TRC_UNSPECIFIED;
507 }
508 exportConfiguration->setProperty(KisImportExportFilter::CICPPrimariesTag,
509 static_cast<int>(primaries));
510 exportConfiguration->setProperty(
512 static_cast<int>(transferFunction));
513 exportConfiguration->setProperty(KisImportExportFilter::HDRTag, cs->hasHighDynamicRange());
514}
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 226 of file KisImportExportManager.cpp.

227{
228 int weight = -1;
229 KisImportExportFilter *filter = 0;
230 QList<KoJsonTrader::Plugin>list = KoJsonTrader::instance()->query("Krita/FileFilter", "");
231
232 Q_FOREACH(const KoJsonTrader::Plugin &loader, list) {
233 QJsonObject json = loader.metaData().value("MetaData").toObject();
234 QString directionKey = direction == Export ? "X-KDE-Export" : "X-KDE-Import";
235
236 if (json.value(directionKey).toString().split(",", Qt::SkipEmptyParts).contains(mimetype)) {
237
238 KPluginFactory *factory = qobject_cast<KPluginFactory *>(loader.instance());
239
240 if (!factory) {
241 warnUI << loader.errorString();
242 continue;
243 }
244
245 QObject* obj = factory->create<KisImportExportFilter>(0);
246 if (!obj || !obj->inherits("KisImportExportFilter")) {
247 delete obj;
248 continue;
249 }
250
251 KisImportExportFilter *f = qobject_cast<KisImportExportFilter*>(obj);
252 if (!f) {
253 delete obj;
254 continue;
255 }
256
257 KIS_ASSERT_RECOVER_NOOP(json.value("X-KDE-Weight").isDouble());
258
259 int w = json.value("X-KDE-Weight").toInt();
260
261 if (w > weight) {
262 delete filter;
263 filter = f;
264 f->setObjectName(loader.fileName());
265 weight = w;
266 }
267 }
268 }
269
270 if (filter) {
271 filter->setMimeType(mimetype);
272 }
273 return filter;
274}
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 864 of file KisImportExportManager.cpp.

865{
866#ifdef Q_OS_ANDROID
867 return getUriForAdditionalFile(location, nullptr);
868#else
869 return location + ".kra";
870#endif
871}
static QString getUriForAdditionalFile(const QString &defaultUri, QWidget *parent)

References getUriForAdditionalFile().

◆ getUriForAdditionalFile()

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

Definition at line 307 of file KisImportExportManager.cpp.

308{
309 KoFileDialog dialog(parent, KoFileDialog::SaveFile, "Save Kra");
310
311 KIS_SAFE_ASSERT_RECOVER_NOOP(!defaultUri.isEmpty());
312
313 dialog.setDirectoryUrl(QUrl(defaultUri));
314 dialog.setMimeTypeFilters(QStringList("application/x-krita"));
315
316 return dialog.filename();
317}
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 158 of file KisImportExportManager.cpp.

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

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 281 of file KisImportExportManager.cpp.

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

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 187 of file KisImportExportManager.cpp.

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

◆ cachedExportFilterMimeType

QString KisImportExportManager::cachedExportFilterMimeType

Definition at line 100 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 98 of file KisImportExportManager.cpp.


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