Krita

Document.cpp
1/*
2 * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6#include "Document.h"
7#include <QPointer>
8#include <QUrl>
9#include <QDomDocument>
10
11#include <KoColorSpaceConstants.h>
12#include <KisDocument.h>
13#include <kis_image.h>
14#include <KisPart.h>
15#include <kis_paint_device.h>
16#include <KisMainWindow.h>
17#include <kis_node_manager.h>
18#include <kis_node_selection_adapter.h>
19#include <KisViewManager.h>
20#include <kis_file_layer.h>
21#include <kis_adjustment_layer.h>
22#include <kis_mask.h>
23#include <kis_clone_layer.h>
24#include <kis_group_layer.h>
25#include <kis_filter_mask.h>
26#include <kis_transform_mask.h>
27#include <kis_transparency_mask.h>
28#include <kis_selection_mask.h>
29#include <lazybrush/kis_colorize_mask.h>
30#include <kis_effect_mask.h>
31#include <kis_paint_layer.h>
32#include <kis_generator_layer.h>
33#include <kis_generator_registry.h>
34#include <kis_shape_layer.h>
35#include <kis_filter_configuration.h>
36#include <kis_filter_registry.h>
37#include <kis_selection.h>
38#include <KisMimeDatabase.h>
39#include <kis_filter_strategy.h>
40#include <kis_guides_config.h>
41#include <kis_coordinates_converter.h>
42#include <kis_time_span.h>
43#include <KisImportExportErrorCode.h>
44#include <kis_types.h>
45#include <kis_annotation.h>
46
47#include <KoColor.h>
48#include <KoColorSpace.h>
49#include <KoColorProfile.h>
50#include <KoColorSpaceRegistry.h>
51#include <KoColorConversionTransformation.h>
52#include <KoDocumentInfo.h>
53#include <KisGlobalResourcesInterface.h>
54
55#include <InfoObject.h>
56#include <Node.h>
57#include <Selection.h>
58#include <LibKisUtils.h>
59
60#include "kis_animation_importer.h"
61#include <kis_canvas2.h>
62#include <KoUpdater.h>
63#include <QMessageBox>
64
65#include <kis_image_animation_interface.h>
66#include <kis_layer_utils.h>
67#include <kis_undo_adapter.h>
68#include <commands/kis_set_global_selection_command.h>
69
70struct Document::Private {
71 Private() {}
72 QPointer<KisDocument> document;
73 bool ownsDocument {false};
74};
75
76Document::Document(KisDocument *document, bool ownsDocument, QObject *parent)
77 : QObject(parent)
78 , d(new Private)
79{
80 d->document = document;
81 d->ownsDocument = ownsDocument;
82}
83
84Document::~Document()
85{
86 if (d->ownsDocument && d->document) {
87 KisPart::instance()->removeDocument(d->document);
88 delete d->document;
89 }
90 delete d;
91}
92
93bool Document::operator==(const Document &other) const
94{
95 return (d->document == other.d->document);
96}
97
98bool Document::operator!=(const Document &other) const
99{
100 return !(operator==(other));
101}
102
104{
105 if (!d->document) return false;
106 return d->document->fileBatchMode();
107}
108
110{
111 if (!d->document) return;
112 d->document->setFileBatchMode(value);
113}
114
116{
118 Q_FOREACH(QPointer<KisView> view, KisPart::instance()->views()) {
119 if (view && view->document() == d->document) {
120 activeNodes << view->currentNode();
121
122 }
123 }
124 if (activeNodes.size() > 0) {
125 QList<Node*> nodes = LibKisUtils::createNodeList(activeNodes, d->document->image());
126 return nodes.first();
127 }
128
129 return 0;
130}
131
133{
134 if (!value) return;
135 if (!value->node()) return;
136 KisMainWindow *mainWin = KisPart::instance()->currentMainwindow();
137 if (!mainWin) return;
138 KisViewManager *viewManager = mainWin->viewManager();
139 if (!viewManager) return;
140 if (viewManager->document() != d->document) return;
141 KisNodeManager *nodeManager = viewManager->nodeManager();
142 if (!nodeManager) return;
143 KisNodeSelectionAdapter *selectionAdapter = nodeManager->nodeSelectionAdapter();
144 if (!selectionAdapter) return;
145 selectionAdapter->setActiveNode(value->node());
146
147}
148
150{
151 if (!d->document) return QList<Node *>();
152 Node n(d->document->image(), d->document->image()->rootLayer());
153 return n.childNodes();
154}
155
156
158{
159 if (!d->document) return 0;
160 KisNodeSP node = KisLayerUtils::findNodeByName(d->document->image()->rootLayer(),name);
161
162 if (node.isNull()) return 0;
163
164 return Node::createNode(d->document->image(), node);
165}
166
168{
169 if (!d->document) return 0;
170
171 KisNodeSP node = KisLayerUtils::findNodeByUuid(d->document->image()->rootLayer(), id);
172
173 if (node.isNull()) return 0;
174 return Node::createNode(d->document->image(), node);
175}
176
177
179{
180 if (!d->document) return "";
181 return d->document->image()->colorSpace()->colorDepthId().id();
182}
183
185{
186 if (!d->document) return "";
187 return d->document->image()->colorSpace()->colorModelId().id();
188}
189
191{
192 if (!d->document) return "";
193 return d->document->image()->colorSpace()->profile()->name();
194}
195
197{
198 if (!d->document) return false;
199 if (!d->document->image()) return false;
200 const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(value);
201 if (!profile) return false;
202 bool retval = d->document->image()->assignImageProfile(profile);
203 d->document->image()->waitForDone();
204 return retval;
205}
206
207bool Document::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
208{
209 if (!d->document) return false;
210 if (!d->document->image()) return false;
211 const KoColorSpace *colorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, colorProfile);
212 if (!colorSpace) return false;
213
214 d->document->image()->convertImageColorSpace(colorSpace,
215 KoColorConversionTransformation::IntentPerceptual,
216 KoColorConversionTransformation::HighQuality | KoColorConversionTransformation::NoOptimization);
217
218 d->document->image()->waitForDone();
219 return true;
220}
221
223{
224 if (!d->document) return QColor();
225 if (!d->document->image()) return QColor();
226
227 const KoColor color = d->document->image()->defaultProjectionColor();
228 return color.toQColor();
229}
230
232{
233 if (!d->document) return false;
234 if (!d->document->image()) return false;
235
236 KoColor background = KoColor(color, d->document->image()->colorSpace());
237 d->document->image()->setDefaultProjectionColor(background);
238
239 d->document->image()->setModifiedWithoutUndo();
240 d->document->image()->initialRefreshGraph();
241
242 return true;
243}
244
246{
247 QDomDocument doc = KisDocument::createDomDocument("document-info"
248 /*DTD name*/, "document-info" /*tag name*/, "1.1");
249 doc = d->document->documentInfo()->save(doc);
250 return doc.toString();
251}
252
254{
255 QDomDocument doc;
256 QString errorMsg;
258 doc.setContent(document, &errorMsg, &errorLine, &errorColumn);
259 d->document->documentInfo()->load(doc);
260}
261
262
264{
265 if (!d->document) return QString();
266 return d->document->path();
267}
268
270{
271 if (!d->document) return;
272 QString mimeType = KisMimeDatabase::mimeTypeForFile(value, false);
273 d->document->setMimeType(mimeType.toLatin1());
274 d->document->setPath(value);
275}
276
278{
279 if (!d->document) return 0;
280 KisImageSP image = d->document->image();
281 if (!image) return 0;
282 return image->height();
283}
284
285void Document::setHeight(int value)
286{
287 if (!d->document) return;
288 if (!d->document->image()) return;
289 resizeImage(d->document->image()->bounds().x(),
290 d->document->image()->bounds().y(),
291 d->document->image()->width(),
292 value);
293}
294
295
297{
298 if (!d->document) return "";
299 return d->document->documentInfo()->aboutInfo("title");
300}
301
303{
304 if (!d->document) return;
305 d->document->documentInfo()->setAboutInfo("title", value);
306}
307
308
310{
311 if (!d->document) return 0;
312 KisImageSP image = d->document->image();
313 if (!image) return 0;
314
315 return qRound(d->document->image()->xRes() * 72);
316}
317
319{
320 if (!d->document) return;
321 KisImageSP image = d->document->image();
322 if (!image) return;
323
324 KisFilterStrategy *strategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
326
327 image->scaleImage(image->size(), value / 72.0, value / 72.0, strategy);
328 image->waitForDone();
329}
330
331
333{
334 if (!d->document) return 0;
335 KisImageSP image = d->document->image();
336 if (!image) return 0;
337
338 return Node::createNode(image, image->root());
339}
340
342{
343 if (!d->document) return 0;
344 if (!d->document->image()) return 0;
345 if (!d->document->image()->globalSelection()) return 0;
346 return new Selection(d->document->image()->globalSelection());
347}
348
350{
351 if (!d->document) return;
352 if (!d->document->image()) return;
353 if (value) {
354 d->document->image()->undoAdapter()->addCommand(new KisSetGlobalSelectionCommand(d->document->image(), value->selection()));
355 }
356 else {
357 d->document->image()->undoAdapter()->addCommand(new KisSetGlobalSelectionCommand(d->document->image(), nullptr));
358 }
359}
360
361
363{
364 if (!d->document) return 0;
365 KisImageSP image = d->document->image();
366 if (!image) return 0;
367 return image->width();
368}
369
370void Document::setWidth(int value)
371{
372 if (!d->document) return;
373 if (!d->document->image()) return;
374 resizeImage(d->document->image()->bounds().x(),
375 d->document->image()->bounds().y(),
376 value,
377 d->document->image()->height());
378}
379
380
382{
383 if (!d->document) return 0;
384 KisImageSP image = d->document->image();
385 if (!image) return 0;
386 return image->bounds().x();
387}
388
390{
391 if (!d->document) return;
392 if (!d->document->image()) return;
393 resizeImage(x,
394 d->document->image()->bounds().y(),
395 d->document->image()->width(),
396 d->document->image()->height());
397}
398
399
401{
402 if (!d->document) return 0;
403 KisImageSP image = d->document->image();
404 if (!image) return 0;
405 return image->bounds().y();
406}
407
409{
410 if (!d->document) return;
411 if (!d->document->image()) return;
412 resizeImage(d->document->image()->bounds().x(),
413 y,
414 d->document->image()->width(),
415 d->document->image()->height());
416}
417
418
419double Document::xRes() const
420{
421 if (!d->document) return 0.0;
422 if (!d->document->image()) return 0.0;
423 return d->document->image()->xRes()*72.0;
424}
425
426void Document::setXRes(double xRes) const
427{
428 if (!d->document) return;
429 KisImageSP image = d->document->image();
430 if (!image) return;
431
432 KisFilterStrategy *strategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
434
435 image->scaleImage(image->size(), xRes / 72.0, image->yRes(), strategy);
436 image->waitForDone();
437}
438
439double Document::yRes() const
440{
441 if (!d->document) return 0.0;
442 if (!d->document->image()) return 0.0;
443 return d->document->image()->yRes()*72.0;
444}
445
446void Document::setYRes(double yRes) const
447{
448 if (!d->document) return;
449 KisImageSP image = d->document->image();
450 if (!image) return;
451
452 KisFilterStrategy *strategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
454
455 image->scaleImage(image->size(), image->xRes(), yRes / 72.0, strategy);
456 image->waitForDone();
457}
458
459
460QByteArray Document::pixelData(int x, int y, int w, int h) const
461{
463
464 if (!d->document) return ba;
465 KisImageSP image = d->document->image();
466 if (!image) return ba;
467
468 KisPaintDeviceSP dev = image->projection();
469 ba.resize(w * h * dev->pixelSize());
470 dev->readBytes(reinterpret_cast<quint8*>(ba.data()), x, y, w, h);
471 return ba;
472}
473
475{
476 bool retval = d->document->closePath(false);
477
478 Q_FOREACH(KisView *view, KisPart::instance()->views()) {
479 if (view->document() == d->document) {
480 view->close();
481 view->closeView();
482 view->deleteLater();
483 }
484 }
485
486 KisPart::instance()->removeDocument(d->document, !d->ownsDocument);
487
488 if (d->ownsDocument) {
489
490 delete d->document;
491 }
492
493 d->document = 0;
494 return retval;
495}
496
497void Document::crop(int x, int y, int w, int h)
498{
499 if (!d->document) return;
500 KisImageSP image = d->document->image();
501 if (!image) return;
502 QRect rc(x, y, w, h);
503 image->cropImage(rc);
504 image->waitForDone();
505}
506
507bool Document::exportImage(const QString &filename, const InfoObject &exportConfiguration)
508{
509 if (!d->document) return false;
510
511 const QString outputFormatString = KisMimeDatabase::mimeTypeForFile(filename, false);
512 const QByteArray outputFormat = outputFormatString.toLatin1();
513
514 return d->document->exportDocumentSync(filename, outputFormat, exportConfiguration.configuration());
515}
516
518{
519 if (!d->document) return;
520 if (!d->document->image()) return;
521 d->document->image()->flatten(0);
522 d->document->image()->waitForDone();
523}
524
525void Document::resizeImage(int x, int y, int w, int h)
526{
527 if (!d->document) return;
528 KisImageSP image = d->document->image();
529 if (!image) return;
530 QRect rc;
531 rc.setX(x);
532 rc.setY(y);
533 rc.setWidth(w);
534 rc.setHeight(h);
535
536 image->resizeImage(rc);
537 image->waitForDone();
538}
539
540void Document::scaleImage(int w, int h, int xres, int yres, QString strategy)
541{
542 if (!d->document) return;
543 KisImageSP image = d->document->image();
544 if (!image) return;
545 QRect rc = image->bounds();
546 rc.setWidth(w);
547 rc.setHeight(h);
548
549 KisFilterStrategy *actualStrategy = KisFilterStrategyRegistry::instance()->get(strategy);
550 if (!actualStrategy) actualStrategy = KisFilterStrategyRegistry::instance()->get("Bicubic");
551
552 image->scaleImage(rc.size(), xres / 72.0, yres / 72.0, actualStrategy);
553 image->waitForDone();
554}
555
556void Document::rotateImage(double radians)
557{
558 if (!d->document) return;
559 KisImageSP image = d->document->image();
560 if (!image) return;
561 image->rotateImage(radians);
562 image->waitForDone();
563}
564
565void Document::shearImage(double angleX, double angleY)
566{
567 if (!d->document) return;
568 KisImageSP image = d->document->image();
569 if (!image) return;
570 image->shear(angleX, angleY);
571 image->waitForDone();
572}
573
575{
576 if (!d->document) return false;
577 if (d->document->path().isEmpty()) return false;
578
579 bool retval = d->document->save(true, 0);
580 d->document->waitForSavingToComplete();
581
582 return retval;
583}
584
585bool Document::saveAs(const QString &filename)
586{
587 if (!d->document) return false;
588
589 setFileName(filename);
590 const QString outputFormatString = KisMimeDatabase::mimeTypeForFile(filename, false);
591 const QByteArray outputFormat = outputFormatString.toLatin1();
592 QString oldPath = d->document->path();
593 d->document->setPath(filename);
594 bool retval = d->document->saveAs(filename, outputFormat, true);
595 d->document->waitForSavingToComplete();
596 d->document->setPath(oldPath);
597
598 return retval;
599}
600
601Node* Document::createNode(const QString &name, const QString &nodeType)
602{
603 if (!d->document) return 0;
604 if (!d->document->image()) return 0;
605 KisImageSP image = d->document->image();
606
607 Node *node = 0;
608
609 if (nodeType.toLower()== "paintlayer") {
610 node = new Node(image, new KisPaintLayer(image, name, OPACITY_OPAQUE_U8));
611 }
612 else if (nodeType.toLower() == "grouplayer") {
613 node = new Node(image, new KisGroupLayer(image, name, OPACITY_OPAQUE_U8));
614 }
615 else if (nodeType.toLower() == "filelayer") {
616 node = new Node(image, new KisFileLayer(image, name, OPACITY_OPAQUE_U8));
617 }
618 else if (nodeType.toLower() == "filterlayer") {
619 node = new Node(image, new KisAdjustmentLayer(image, name, 0, 0));
620 }
621 else if (nodeType.toLower() == "filllayer") {
622 node = new Node(image, new KisGeneratorLayer(image, name, 0, 0));
623 }
624 else if (nodeType.toLower() == "clonelayer") {
625 node = new Node(image, new KisCloneLayer(0, image, name, OPACITY_OPAQUE_U8));
626 }
627 else if (nodeType.toLower() == "vectorlayer") {
628 node = new Node(image, new KisShapeLayer(d->document->shapeController(), image, name, OPACITY_OPAQUE_U8));
629 }
630 else if (nodeType.toLower() == "transparencymask") {
631 node = new Node(image, new KisTransparencyMask(image, name));
632 }
633 else if (nodeType.toLower() == "filtermask") {
634 node = new Node(image, new KisFilterMask(image, name));
635 }
636 else if (nodeType.toLower() == "transformmask") {
637 node = new Node(image, new KisTransformMask(image, name));
638 }
639 else if (nodeType.toLower() == "selectionmask") {
640 node = new Node(image, new KisSelectionMask(image, name));
641 }
642 else if (nodeType.toLower() == "colorizemask") {
643 node = new Node(image, new KisColorizeMask(image, name));
644 }
645
646 return node;
647}
648
650{
651 if (!d->document) return 0;
652 if (!d->document->image()) return 0;
653 KisImageSP image = d->document->image();
654
655 return new GroupLayer(image, name);
656}
657
658FileLayer *Document::createFileLayer(const QString &name, const QString fileName, const QString scalingMethod, const QString scalingFilter)
659{
660 if (!d->document) return 0;
661 if (!d->document->image()) return 0;
662 KisImageSP image = d->document->image();
663
664 return new FileLayer(image, name, this->fileName(), fileName, scalingMethod, scalingFilter);
665}
666
668{
669 if (!d->document) return 0;
670 if (!d->document->image()) return 0;
671 KisImageSP image = d->document->image();
672
673 return new FilterLayer(image, name, filter, selection);
674}
675
676FillLayer *Document::createFillLayer(const QString &name, const QString generatorName, InfoObject &configuration, Selection &selection)
677{
678 if (!d->document) return 0;
679 if (!d->document->image()) return 0;
680 KisImageSP image = d->document->image();
681
682 KisGeneratorSP generator = KisGeneratorRegistry::instance()->value(generatorName);
683 if (generator) {
684
685 KisFilterConfigurationSP config = generator->factoryConfiguration(KisGlobalResourcesInterface::instance());
686 Q_FOREACH(const QString property, configuration.properties().keys()) {
687 config->setProperty(property, configuration.property(property));
688 }
689
690 return new FillLayer(image, name, config, selection);
691 }
692 return 0;
693}
694
696{
697 if (!d->document) return 0;
698 if (!d->document->image()) return 0;
699 KisImageSP image = d->document->image();
700 KisLayerSP layer = qobject_cast<KisLayer*>(source->node().data());
701
702 return new CloneLayer(image, name, layer);
703}
704
706{
707 if (!d->document) return 0;
708 if (!d->document->image()) return 0;
709 KisImageSP image = d->document->image();
710
711 return new VectorLayer(d->document->shapeController(), image, name);
712}
713
714FilterMask *Document::createFilterMask(const QString &name, Filter &filter, const Node *selection_source)
715{
716 if (!d->document)
717 return 0;
718
719 if (!d->document->image())
720 return 0;
721
723 return 0;
724
726 if(layer.isNull())
727 return 0;
728
729 KisImageSP image = d->document->image();
730 FilterMask* mask = new FilterMask(image, name, filter);
731 qobject_cast<KisMask*>(mask->node().data())->initSelection(layer);
732
733 return mask;
734}
735
737{
738 if (!d->document)
739 return 0;
740
741 if (!d->document->image())
742 return 0;
743
744 KisImageSP image = d->document->image();
745 FilterMask* mask = new FilterMask(image, name, filter);
746 qobject_cast<KisMask*>(mask->node().data())->setSelection(selection.selection());
747
748 return mask;
749}
750
752{
753 if (!d->document) return 0;
754 if (!d->document->image()) return 0;
755 KisImageSP image = d->document->image();
756
757 return new SelectionMask(image, name);
758}
759
761{
762 if (!d->document) return 0;
763 if (!d->document->image()) return 0;
764 KisImageSP image = d->document->image();
765
766 return new TransparencyMask(image, name);
767}
768
770{
771 if (!d->document) return 0;
772 if (!d->document->image()) return 0;
773 KisImageSP image = d->document->image();
774
775 return new TransformMask(image, name);
776}
777
779{
780 if (!d->document) return 0;
781 if (!d->document->image()) return 0;
782 KisImageSP image = d->document->image();
783
784 return new ColorizeMask(image, name);
785}
786
787QImage Document::projection(int x, int y, int w, int h) const
788{
789 if (!d->document || !d->document->image()) return QImage();
790 return d->document->image()->convertToQImage(x, y, w, h, 0);
791}
792
793QImage Document::thumbnail(int w, int h) const
794{
795 if (!d->document || !d->document->image()) return QImage();
796 return d->document->generatePreview(QSize(w, h)).toImage();
797}
798
799
801{
802 if (!d->document || !d->document->image()) return;
803 d->document->image()->barrierLock();
804}
805
807{
808 if (!d->document || !d->document->image()) return;
809 d->document->image()->unlock();
810}
811
813{
814 if (!d->document || !d->document->image()) return;
815 d->document->image()->waitForDone();
816}
817
819{
820 if (!d->document || !d->document->image()) return false;
821 return d->document->image()->tryBarrierLock();
822}
823
825{
826 if (!d->document || !d->document->image()) return;
827 d->document->image()->refreshGraph();
828}
829
831{
832 QList<qreal> lines;
833 if (!d->document || !d->document->image()) return lines;
835 converter.setImage(d->document->image());
836 QTransform transform = converter.imageToDocumentTransform().inverted();
837 QList<qreal> untransformedLines = d->document->guidesConfig().horizontalGuideLines();
838 for (int i = 0; i< untransformedLines.size(); i++) {
839 qreal line = untransformedLines[i];
840 lines.append(transform.map(QPointF(line, line)).x());
841 }
842 return lines;
843}
844
846{
847 QList<qreal> lines;
848 if (!d->document || !d->document->image()) return lines;
850 converter.setImage(d->document->image());
851 QTransform transform = converter.imageToDocumentTransform().inverted();
852 QList<qreal> untransformedLines = d->document->guidesConfig().verticalGuideLines();
853 for (int i = 0; i< untransformedLines.size(); i++) {
854 qreal line = untransformedLines[i];
855 lines.append(transform.map(QPointF(line, line)).y());
856 }
857 return lines;
858}
859
861{
862 return d->document->guidesConfig().showGuides();
863}
864
866{
867 return d->document->guidesConfig().lockGuides();
868}
869
871{
872 if (!d->document) return 0;
873 QPointer<KisDocument> clone = d->document->clone();
874
875 /// We set ownsDocument to true, it will be reset
876 /// automatically as soon as we create the first
877 /// view for the document
878 Document * newDocument = new Document(clone, true);
879 return newDocument;
880}
881
883{
884 if (!d->document) return;
885 KisGuidesConfig config = d->document->guidesConfig();
887 converter.setImage(d->document->image());
888 QTransform transform = converter.imageToDocumentTransform();
890 for (int i = 0; i< lines.size(); i++) {
891 qreal line = lines[i];
892 transformedLines.append(transform.map(QPointF(line, line)).x());
893 }
894 config.setHorizontalGuideLines(transformedLines);
895 d->document->setGuidesConfig(config);
896}
897
899{
900 if (!d->document) return;
901 KisGuidesConfig config = d->document->guidesConfig();
903 converter.setImage(d->document->image());
904 QTransform transform = converter.imageToDocumentTransform();
906 for (int i = 0; i< lines.size(); i++) {
907 qreal line = lines[i];
908 transformedLines.append(transform.map(QPointF(line, line)).y());
909 }
910 config.setVerticalGuideLines(transformedLines);
911 d->document->setGuidesConfig(config);
912}
913
915{
916 if (!d->document) return;
917 KisGuidesConfig config = d->document->guidesConfig();
918 config.setShowGuides(visible);
919 d->document->setGuidesConfig(config);
920}
921
923{
924 if (!d->document) return;
925 KisGuidesConfig config = d->document->guidesConfig();
926 config.setLockGuides(locked);
927 d->document->setGuidesConfig(config);
928}
929
931{
932 if (!d->document) return false;
933 return d->document->isModified();
934}
935
936void Document::setModified(bool modified)
937{
938 if (!d->document) return;
939 d->document->setModified(modified);
940}
941
943{
944 if (!d->document) return QRect();
945 return d->document->image()->bounds();
946}
947
948QPointer<KisDocument> Document::document() const
949{
950 return d->document;
951}
952
953void Document::setOwnsDocument(bool ownsDocument)
954{
955 d->ownsDocument = ownsDocument;
956}
957
958/* Animation related function */
959
960bool Document::importAnimation(const QList<QString> &files, int firstFrame, int step)
961{
962 KisView *activeView = KisPart::instance()->currentMainwindow()->activeView();
963
965 if (activeView && d->document->fileBatchMode()) {
966 updater = activeView->viewManager()->createUnthreadedUpdater(i18n("Import frames"));
967 }
968
969 KisAnimationImporter importer(d->document->image(), updater);
971
972 return status.isOk();
973}
974
976{
977 if (!d->document) return false;
978 if (!d->document->image()) return false;
979
980 return d->document->image()->animationInterface()->framerate();
981}
982
984{
985 if (!d->document) return;
986 if (!d->document->image()) return;
987
988 d->document->image()->animationInterface()->setFramerate(fps);
989}
990
992{
993 if (!d->document) return;
994 if (!d->document->image()) return;
995
996 d->document->image()->animationInterface()->setDocumentRangeStartFrame(startTime);
997}
998
999
1001{
1002 if (!d->document) return false;
1003 if (!d->document->image()) return false;
1004
1005 return d->document->image()->animationInterface()->documentPlaybackRange().start();
1006}
1007
1008
1010{
1011 if (!d->document) return;
1012 if (!d->document->image()) return;
1013
1014 d->document->image()->animationInterface()->setDocumentRangeEndFrame(endTime);
1015}
1016
1017
1019{
1020 if (!d->document) return false;
1021 if (!d->document->image()) return false;
1022
1023 return d->document->image()->animationInterface()->documentPlaybackRange().end();
1024}
1025
1027{
1028 if (!d->document) return false;
1029 if (!d->document->image()) return false;
1030
1031 return d->document->image()->animationInterface()->totalLength();
1032}
1033
1035{
1036 if (!d->document) return;
1037 if (!d->document->image()) return;
1038
1039 const KisTimeSpan newTimeRange = KisTimeSpan::fromTimeWithDuration(start, (stop-start));
1040 d->document->image()->animationInterface()->setActivePlaybackRange(newTimeRange);
1041}
1042
1044{
1045 if (!d->document) return false;
1046 if (!d->document->image()) return false;
1047
1048 return d->document->image()->animationInterface()->activePlaybackRange().start();
1049}
1050
1052{
1053 if (!d->document) return false;
1054 if (!d->document->image()) return false;
1055
1056 return d->document->image()->animationInterface()->activePlaybackRange().end();
1057}
1058
1060{
1061 if (!d->document) return false;
1062 if (!d->document->image()) return false;
1063
1064 return d->document->image()->animationInterface()->currentTime();
1065}
1066
1068{
1069 if (!d->document) return;
1070 if (!d->document->image()) return;
1071
1072 return d->document->image()->animationInterface()->requestTimeSwitchWithUndo(time);
1073}
1074
1076{
1077 if (!d->document) return QStringList();
1078
1079 QStringList types;
1080
1081 KisImageSP image = d->document->image().toStrongRef();
1082
1083 if (!image) return QStringList();
1084
1085 vKisAnnotationSP_it beginIt = image->beginAnnotations();
1086 vKisAnnotationSP_it endIt = image->endAnnotations();
1087
1089 while (it != endIt) {
1090 if (!(*it) || (*it)->type().isEmpty()) {
1091 qWarning() << "Warning: empty annotation";
1092 it++;
1093 continue;
1094 }
1095 types << (*it)->type();
1096
1097 it++;
1098 }
1099 return types;
1100}
1101
1103{
1104 KisImageSP image = d->document->image().toStrongRef();
1105 KisAnnotationSP annotation = image->annotation(type);
1106 return annotation->description();
1107}
1108
1110{
1111 KisImageSP image = d->document->image().toStrongRef();
1112 KisAnnotationSP annotation = image->annotation(type);
1113 if (annotation) {
1114 return annotation->annotation();
1115 }
1116 else {
1117 return QByteArray();
1118 }
1119}
1120
1121void Document::setAnnotation(const QString &key, const QString &description, const QByteArray &annotation)
1122{
1123 KisAnnotation *a = new KisAnnotation(key, description, annotation);
1124 KisImageSP image = d->document->image().toStrongRef();
1125 image->addAnnotation(a);
1126
1127}
1128
1130{
1131 KisImageSP image = d->document->image().toStrongRef();
1132 image->removeAnnotation(type);
1133}
The CloneLayer class A clone layer is a layer that takes a reference inside the image and shows the e...
Definition CloneLayer.h:26
The ColorizeMask class A colorize mask is a mask type node that can be used to color in line art.
The Document class encapsulates a Krita Document/Image.
Definition Document.h:34
QImage projection(int x=0, int y=0, int w=0, int h=0) const
projection creates a QImage from the rendered image or a cutout rectangle.
Definition Document.cpp:787
bool guidesVisible() const
guidesVisible Returns guide visibility.
Definition Document.cpp:860
int resolution() const
Definition Document.cpp:309
TransformMask * createTransformMask(const QString &name)
createTransformMask Creates a transform mask, which can be used to apply a transformation non-destruc...
Definition Document.cpp:769
int animationLength()
get total frame range for animation
void setGuidesLocked(bool locked)
setGuidesLocked set guides locked on this document
Definition Document.cpp:922
void setFramesPerSecond(int fps)
set frames per second of document
Definition Document.cpp:983
void setFullClipRangeEndTime(int endTime)
set full clip range end time
void setSelection(Selection *value)
setSelection set or replace the global selection
Definition Document.cpp:349
void setFullClipRangeStartTime(int startTime)
set start time of animation
Definition Document.cpp:991
int height() const
Definition Document.cpp:277
SelectionMask * createSelectionMask(const QString &name)
createSelectionMask Creates a selection mask, which can be used to store selections.
Definition Document.cpp:751
QList< Node * > topLevelNodes() const
toplevelNodes return a list with all top level nodes in the image graph
Definition Document.cpp:149
int currentTime()
get current frame selected of animation
bool close()
close Close the document: remove it from Krita's internal list of documents and close all views.
Definition Document.cpp:474
bool modified() const
modified returns true if the document has unsaved modifications.
Definition Document.cpp:930
void setDocumentInfo(const QString &document)
setDocumentInfo set the Document information to the information contained in document
Definition Document.cpp:253
int fullClipRangeEndTime()
get the full clip range end time
QImage thumbnail(int w, int h) const
thumbnail create a thumbnail of the given dimensions.
Definition Document.cpp:793
ColorizeMask * createColorizeMask(const QString &name)
createColorizeMask Creates a colorize mask, which can be used to color fill via keystrokes.
Definition Document.cpp:778
void flatten()
flatten all layers in the image
Definition Document.cpp:517
void setXOffset(int x)
setXOffset sets the left edge of the canvas to x.
Definition Document.cpp:389
bool importAnimation(const QList< QString > &files, int firstFrame, int step)
Import an image sequence of files from a directory.
Definition Document.cpp:960
int fullClipRangeStartTime()
get the full clip range start time
bool setBackgroundColor(const QColor &color)
setBackgroundColor sets the background color of the document.
Definition Document.cpp:231
void setActiveNode(Node *value)
setActiveNode make the given node active in the currently active view and window
Definition Document.cpp:132
void setYOffset(int y)
setYOffset sets the top edge of the canvas to y.
Definition Document.cpp:408
QString name() const
Definition Document.cpp:296
void setHorizontalGuides(const QList< qreal > &lines)
setHorizontalGuides replace all existing horizontal guides with the entries in the list.
Definition Document.cpp:882
QString colorProfile() const
Definition Document.cpp:190
void resizeImage(int x, int y, int w, int h)
resizeImage resizes the canvas to the given left edge, top edge, width and height.
Definition Document.cpp:525
Node * rootNode() const
rootNode the root node is the invisible group layer that contains the entire node hierarchy.
Definition Document.cpp:332
QString colorModel() const
colorModel retrieve the current color model of this document:
Definition Document.cpp:184
bool saveAs(const QString &filename)
saveAs save the document under the filename.
Definition Document.cpp:585
QString fileName() const
Definition Document.cpp:263
void unlock()
Unlocks the image and starts/resumes all the pending internal jobs.
Definition Document.cpp:806
Node * activeNode() const
activeNode retrieve the node that is currently active in the currently active window
Definition Document.cpp:115
QStringList annotationTypes() const
annotationTypes returns the list of annotations present in the document.
void rotateImage(double radians)
rotateImage Rotate the image by the given radians.
Definition Document.cpp:556
int playBackEndTime()
get end time of current playback
FillLayer * createFillLayer(const QString &name, const QString generatorName, InfoObject &configuration, Selection &selection)
createFillLayer creates a fill layer object, which is a layer
Definition Document.cpp:676
bool setColorProfile(const QString &colorProfile)
setColorProfile set the color profile of the image to the given profile.
Definition Document.cpp:196
void setPlayBackRange(int start, int stop)
set temporary playback range of document
void scaleImage(int w, int h, int xres, int yres, QString strategy)
scaleImage
Definition Document.cpp:540
double yRes() const
Definition Document.cpp:439
Document * clone() const
clone create a shallow clone of this document.
Definition Document.cpp:870
void setName(QString value)
setName sets the name of the document to value.
Definition Document.cpp:302
void setXRes(double xRes) const
setXRes set the horizontal resolution of the image to xRes in pixels per inch
Definition Document.cpp:426
CloneLayer * createCloneLayer(const QString &name, const Node *source)
createCloneLayer
Definition Document.cpp:695
bool setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
setColorSpace convert the nodes and the image to the given colorspace.
Definition Document.cpp:207
int yOffset() const
Definition Document.cpp:400
void removeAnnotation(const QString &type)
removeAnnotation remove the specified annotation from the image
bool batchmode() const
Batchmode means that no actions on the document should show dialogs or popups.
Definition Document.cpp:103
void waitForDone()
Wait for all the internal image jobs to complete and return without locking the image.
Definition Document.cpp:812
void setGuidesVisible(bool visible)
setGuidesVisible set guides visible on this document.
Definition Document.cpp:914
void setModified(bool modified)
setModified sets the modified status of the document
Definition Document.cpp:936
QList< qreal > verticalGuides() const
verticalGuides The vertical guide lines.
Definition Document.cpp:845
void refreshProjection()
Starts a synchronous recomposition of the projection: everything will wait until the image is fully r...
Definition Document.cpp:824
bool guidesLocked() const
guidesLocked Returns guide lockedness.
Definition Document.cpp:865
QString documentInfo() const
documentInfo creates and XML document representing document and author information.
Definition Document.cpp:245
Node * nodeByUniqueID(const QUuid &id) const
nodeByUniqueID searches the node tree for a node with the given name and returns it.
Definition Document.cpp:167
VectorLayer * createVectorLayer(const QString &name)
createVectorLayer Creates a vector layer that can contain vector shapes.
Definition Document.cpp:705
Node * createNode(const QString &name, const QString &nodeType)
Definition Document.cpp:601
QList< qreal > horizontalGuides() const
horizontalGuides The horizontal guides.
Definition Document.cpp:830
void setWidth(int value)
setWidth resize the document to
Definition Document.cpp:370
int width() const
Definition Document.cpp:362
void setVerticalGuides(const QList< qreal > &lines)
setVerticalGuides replace all existing horizontal guides with the entries in the list.
Definition Document.cpp:898
bool tryBarrierLock()
Tries to lock the image without waiting for the jobs to finish.
Definition Document.cpp:818
QString colorDepth() const
colorDepth A string describing the color depth of the image:
Definition Document.cpp:178
bool save()
save the image to its currently set path.
Definition Document.cpp:574
void setYRes(double yRes) const
setYRes set the vertical resolution of the image to yRes in pixels per inch
Definition Document.cpp:446
void setFileName(QString value)
setFileName set the full path of the document to
Definition Document.cpp:269
FileLayer * createFileLayer(const QString &name, const QString fileName, const QString scalingMethod, const QString scalingFilter="Bicubic")
createFileLayer returns a layer that shows an external image.
Definition Document.cpp:658
int playBackStartTime()
get start time of current playback
TransparencyMask * createTransparencyMask(const QString &name)
createTransparencyMask Creates a transparency mask, which can be used to assign transparency to regio...
Definition Document.cpp:760
bool exportImage(const QString &filename, const InfoObject &exportConfiguration)
exportImage export the image, without changing its URL to the given path.
Definition Document.cpp:507
void setBatchmode(bool value)
Set batchmode to value.
Definition Document.cpp:109
void setAnnotation(const QString &type, const QString &description, const QByteArray &annotation)
setAnnotation Add the given annotation to the document
int framesPerSecond()
frames per second of document
Definition Document.cpp:975
void crop(int x, int y, int w, int h)
crop the image to rectangle described by x, y, w and h
Definition Document.cpp:497
int xOffset() const
Definition Document.cpp:381
Selection * selection() const
selection Create a Selection object around the global selection, if there is one.
Definition Document.cpp:341
void setResolution(int value)
setResolution set the resolution of the image; this does not scale the image
Definition Document.cpp:318
QColor backgroundColor()
backgroundColor returns the current background color of the document.
Definition Document.cpp:222
QByteArray pixelData(int x, int y, int w, int h) const
pixelData reads the given rectangle from the image projection and returns it as a byte array.
Definition Document.cpp:460
QRect bounds() const
bounds return the bounds of the image
Definition Document.cpp:942
void lock()
[low-level] Lock the image without waiting for all the internal job queues are processed
Definition Document.cpp:800
QString annotationDescription(const QString &type) const
annotationDescription gets the pretty description for the current annotation
void shearImage(double angleX, double angleY)
shearImage shear the whole image.
Definition Document.cpp:565
FilterLayer * createFilterLayer(const QString &name, Filter &filter, Selection &selection)
createFilterLayer creates a filter layer, which is a layer that represents a filter applied non-destr...
Definition Document.cpp:667
Node * nodeByName(const QString &name) const
nodeByName searches the node tree for a node with the given name and returns it
Definition Document.cpp:157
FilterMask * createFilterMask(const QString &name, Filter &filter, Selection &selection)
createFilterMask Creates a filter mask object that much like a filterlayer can apply a filter non-des...
Definition Document.cpp:736
double xRes() const
Definition Document.cpp:419
QByteArray annotation(const QString &type)
annotation the actual data for the annotation for this type.
void setCurrentTime(int time)
set current time of document's animation
GroupLayer * createGroupLayer(const QString &name)
createGroupLayer Returns a grouplayer object.
Definition Document.cpp:649
void setHeight(int value)
setHeight resize the document to
Definition Document.cpp:285
The FileLayer class A file layer is a layer that can reference an external image and show said refere...
Definition FileLayer.h:27
The FillLayer class A fill layer is much like a filter layer in that it takes a name and filter.
Definition FillLayer.h:25
The FilterLayer class A filter layer will, when compositing, take the composited image up to the poin...
Definition FilterLayer.h:34
The FilterMask class A filter mask, unlike a filter layer, will add a non-destructive filter to the c...
Definition FilterMask.h:29
The GroupLayer class A group layer is a layer that can contain other layers.
Definition GroupLayer.h:30
InfoObject wrap a properties map.
Definition InfoObject.h:20
QVariant property(const QString &key)
return the value for the property identified by key, or None if there is no such key.
QMap< QString, QVariant > properties() const
Return all properties this InfoObject manages.
Node represents a layer or mask in a Krita image's Node hierarchy.
Definition Node.h:22
QList< Node * > childNodes() const
childNodes
Definition Node.cpp:205
The SelectionMask class A selection mask is a mask type node that can be used to store selections.
Selection represents a selection on Krita.
Definition Selection.h:31
The TransformMask class A transform mask is a mask type node that can be used to store transformation...
The TransparencyMask class A transparency mask is a mask type node that can be used to show and hide ...
The VectorLayer class A vector layer is a special layer that stores and shows vector shapes.
Definition VectorLayer.h:32
void stop(Ekos::AlignState mode)
Q_SCRIPTABLE Q_NOREPLY void start()
Q_SCRIPTABLE CaptureState status()
QString i18n(const char *text, const TYPE &arg...)
ParseResult setContent(QAnyStringView text, ParseOptions options)
QString toString(int indent) const const
void append(QList< T > &&value)
qsizetype size() const const
QVariant property(const char *name) const const
T qobject_cast(QObject *object)
QByteArray toLatin1() const const
QString toLower() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:53 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.