00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qapplication.h>
00024 #include <qdom.h>
00025 #include <qimage.h>
00026 #include <qpainter.h>
00027 #include <qtl.h>
00028 #include <qstringlist.h>
00029 #include <qwidget.h>
00030 #include <qpaintdevicemetrics.h>
00031
00032
00033 #include <dcopobject.h>
00034 #include <kapplication.h>
00035 #include <kcommand.h>
00036 #include <kdebug.h>
00037 #include <kimageio.h>
00038 #include <kfiledialog.h>
00039 #include <kglobal.h>
00040 #include <kmimetype.h>
00041 #include <knotifyclient.h>
00042 #include <klocale.h>
00043 #include <kmessagebox.h>
00044
00045
00046 #include <KoFilterManager.h>
00047 #include <KoMainWindow.h>
00048 #include <KoQueryTrader.h>
00049 #include <KoStore.h>
00050 #include <KoStoreDevice.h>
00051 #include <KoTemplateChooseDia.h>
00052 #include <KoApplication.h>
00053 #include <KoCommandHistory.h>
00054
00055
00056 #include <kis_clipboard.h>
00057 #include <kis_meta_registry.h>
00058 #include "kis_annotation.h"
00059 #include "kis_types.h"
00060 #include "kis_config.h"
00061 #include "kis_debug_areas.h"
00062 #include "kis_doc.h"
00063 #include "kis_factory.h"
00064 #include "kis_image.h"
00065 #include "kis_layer.h"
00066 #include "kis_paint_layer.h"
00067 #include "kis_nameserver.h"
00068 #include "kis_painter.h"
00069 #include "kis_selection.h"
00070 #include "kis_fill_painter.h"
00071 #include "kis_command.h"
00072 #include "kis_view.h"
00073 #include "kis_colorspace.h"
00074 #include "kis_colorspace_factory_registry.h"
00075 #include "kis_profile.h"
00076 #include "kis_id.h"
00077 #include "kis_part_layer.h"
00078 #include "kis_doc_iface.h"
00079 #include "kis_paint_device_action.h"
00080 #include "kis_custom_image_widget.h"
00081 #include "kis_load_visitor.h"
00082 #include "kis_save_visitor.h"
00083 #include "kis_savexml_visitor.h"
00084
00085 static const char *CURRENT_DTD_VERSION = "1.3";
00086
00092 #define APP_MIMETYPE "application/x-krita"
00093
00097 #define NATIVE_MIMETYPE "application/x-kra"
00098
00099 namespace {
00100 class KisCommandImageMv : public KisCommand {
00101 typedef KisCommand super;
00102
00103 public:
00104 KisCommandImageMv(KisDoc *doc,
00105 KisUndoAdapter *adapter,
00106 const QString& name,
00107 const QString& oldName) : super(i18n("Rename Image"), adapter)
00108 {
00109 m_doc = doc;
00110 m_name = name;
00111 m_oldName = oldName;
00112 }
00113
00114 virtual ~KisCommandImageMv()
00115 {
00116 }
00117
00118 virtual void execute()
00119 {
00120 adapter()->setUndo(false);
00121 m_doc->renameImage(m_oldName, m_name);
00122 adapter()->setUndo(true);
00123 }
00124
00125 virtual void unexecute()
00126 {
00127 adapter()->setUndo(false);
00128 m_doc->renameImage(m_name, m_oldName);
00129 adapter()->setUndo(true);
00130 }
00131
00132 private:
00133 KisDoc *m_doc;
00134 QString m_name;
00135 QString m_oldName;
00136 };
00137
00138 }
00139
00140 KisDoc::KisDoc(QWidget *parentWidget, const char *widgetName, QObject *parent, const char *name, bool singleViewMode) :
00141 super(parentWidget, widgetName, parent, name, singleViewMode)
00142 {
00143
00144 m_undo = false;
00145 m_dcop = 0;
00146 m_cmdHistory = 0;
00147 m_nserver = 0;
00148 m_currentImage = 0;
00149 m_currentMacro = 0;
00150 m_macroNestDepth = 0;
00151 m_ioProgressBase = 0;
00152 m_ioProgressTotalSteps = 0;
00153
00154 setInstance( KisFactory::instance(), false );
00155 setTemplateType( "krita_template" );
00156
00157 init();
00158
00159 if (name)
00160 dcopObject();
00161 }
00162
00163 KisDoc::~KisDoc()
00164 {
00165 delete m_cmdHistory;
00166 delete m_nserver;
00167 m_undoListeners.setAutoDelete(false);
00168 delete m_dcop;
00169 }
00170
00171 QCString KisDoc::mimeType() const
00172 {
00173 return APP_MIMETYPE;
00174 }
00175
00176 DCOPObject *KisDoc::dcopObject()
00177 {
00178 if (!m_dcop) {
00179 m_dcop = new KisDocIface(this);
00180 Q_CHECK_PTR(m_dcop);
00181 }
00182 return m_dcop;
00183 }
00184
00185 bool KisDoc::initDoc(InitDocFlags flags, QWidget* parentWidget)
00186 {
00187 if (!init())
00188 return false;
00189
00190 bool ok = false;
00191
00192 QString file;
00193 KoTemplateChooseDia::DialogType dlgtype;
00194
00195 if (flags != KoDocument::InitDocFileNew) {
00196 dlgtype = KoTemplateChooseDia::Everything;
00197 } else {
00198 dlgtype = KoTemplateChooseDia::OnlyTemplates;
00199 }
00200
00201 KoTemplateChooseDia::ReturnType ret =
00202 KoTemplateChooseDia::choose(KisFactory::instance(),
00203 file,
00204 dlgtype,
00205 "krita_template",
00206 parentWidget);
00207 setUndo(false);
00208
00209 if (ret == KoTemplateChooseDia::Template) {
00210 resetURL();
00211 ok = loadNativeFormat( file );
00212 setEmpty();
00213 ok = true;
00214
00215 } else if (ret == KoTemplateChooseDia::File) {
00216 KURL url( file );
00217 ok = openURL(url);
00218 } else if (ret == KoTemplateChooseDia::Empty) {
00219 setEmpty();
00220 ok = true;
00221 }
00222
00223 setModified(false);
00224 KisConfig cfg;
00225 setUndo(cfg.undoEnabled());
00226
00227 return ok;
00228 }
00229
00230 void KisDoc::openExistingFile(const QString& file)
00231 {
00232 setUndo(false);
00233
00234 KoDocument::openExistingFile(file);
00235
00236 setUndo(true);
00237 }
00238
00239 void KisDoc::openTemplate(const QString& file)
00240 {
00241 setUndo(false);
00242
00243 KoDocument::openTemplate(file);
00244
00245 setUndo(true);
00246 }
00247
00248 bool KisDoc::init()
00249 {
00250 if (m_cmdHistory) {
00251 delete m_cmdHistory;
00252 m_cmdHistory = 0;
00253 }
00254
00255 if (m_nserver) {
00256 delete m_nserver;
00257 m_nserver = 0;
00258 }
00259
00260 m_cmdHistory = new KoCommandHistory(actionCollection(), true);
00261 Q_CHECK_PTR(m_cmdHistory);
00262
00263 connect(m_cmdHistory, SIGNAL(documentRestored()), this, SLOT(slotDocumentRestored()));
00264 connect(m_cmdHistory, SIGNAL(commandExecuted(KCommand *)), this, SLOT(slotCommandExecuted(KCommand *)));
00265 setUndo(true);
00266
00267 m_nserver = new KisNameServer(i18n("Image %1"), 1);
00268 Q_CHECK_PTR(m_nserver);
00269
00270 if (!KisMetaRegistry::instance()->csRegistry()->exists(KisID("RGBA",""))) {
00271 KMessageBox::sorry(0, i18n("No colorspace modules loaded: cannot run Krita"));
00272 return false;
00273 }
00274
00275 m_undoListeners.setAutoDelete(false);
00276
00277 return true;
00278 }
00279
00280 QDomDocument KisDoc::saveXML()
00281 {
00282 QDomDocument doc = createDomDocument("DOC", CURRENT_DTD_VERSION);
00283 QDomElement root = doc.documentElement();
00284
00285 root.setAttribute("editor", "Krita");
00286 root.setAttribute("depth", sizeof(Q_UINT8));
00287 root.setAttribute("syntaxVersion", "1");
00288
00289 root.appendChild(saveImage(doc, m_currentImage));
00290
00291 return doc;
00292 }
00293
00294 bool KisDoc::loadOasis( const QDomDocument&, KoOasisStyles&, const QDomDocument&, KoStore* )
00295 {
00296
00297 return false;
00298 }
00299
00300
00301 bool KisDoc::saveOasis( KoStore*, KoXmlWriter* )
00302 {
00303
00304 return false;
00305 }
00306
00307 bool KisDoc::loadXML(QIODevice *, const QDomDocument& doc)
00308 {
00309 QDomElement root;
00310 QString attr;
00311 QDomNode node;
00312 KisImageSP img;
00313
00314 if (!init())
00315 return false;
00316 if (doc.doctype().name() != "DOC")
00317 return false;
00318 root = doc.documentElement();
00319 attr = root.attribute("syntaxVersion");
00320 if (attr.toInt() > 1)
00321 return false;
00322 if ((attr = root.attribute("depth")).isNull())
00323 return false;
00324 m_conversionDepth = attr.toInt();
00325
00326 if (!root.hasChildNodes()) {
00327 return false;
00328 }
00329
00330 setUndo(false);
00331
00332 for (node = root.firstChild(); !node.isNull(); node = node.nextSibling()) {
00333 if (node.isElement()) {
00334 if (node.nodeName() == "IMAGE") {
00335 QDomElement elem = node.toElement();
00336 if (!(img = loadImage(elem)))
00337 return false;
00338 m_currentImage = img;
00339 } else {
00340 return false;
00341 }
00342 }
00343 }
00344
00345 emit loadingFinished();
00346 return true;
00347 }
00348
00349 bool KisDoc::loadChildren(KoStore* store) {
00350 QPtrListIterator<KoDocumentChild> it(children());
00351 for( ; it.current(); ++it ) {
00352 if (!it.current()->loadDocument(store)) {
00353 return false;
00354 }
00355 }
00356 return true;
00357 }
00358
00359 QDomElement KisDoc::saveImage(QDomDocument& doc, KisImageSP img)
00360 {
00361 QDomElement image = doc.createElement("IMAGE");
00362
00363 Q_ASSERT(img);
00364 image.setAttribute("name", img->name());
00365 image.setAttribute("mime", "application/x-kra");
00366 image.setAttribute("width", img->width());
00367 image.setAttribute("height", img->height());
00368 image.setAttribute("colorspacename", img->colorSpace()->id().id());
00369 image.setAttribute("description", img->description());
00370
00371 if (img->getProfile() && img->getProfile()-> valid())
00372 image.setAttribute("profile", img->getProfile()->productName());
00373 image.setAttribute("x-res", img->xRes());
00374 image.setAttribute("y-res", img->yRes());
00375
00376 Q_UINT32 count=0;
00377 KisSaveXmlVisitor visitor(doc, image, count, true);
00378
00379 m_currentImage->rootLayer()->accept(visitor);
00380
00381 return image;
00382 }
00383
00384 KisImageSP KisDoc::loadImage(const QDomElement& element)
00385 {
00386
00387 KisConfig cfg;
00388 QString attr;
00389 QDomNode node;
00390 QDomNode child;
00391 KisImageSP img;
00392 QString name;
00393 Q_INT32 width;
00394 Q_INT32 height;
00395 QString description;
00396 QString profileProductName;
00397 double xres;
00398 double yres;
00399 QString colorspacename;
00400 KisColorSpace * cs;
00401
00402 if ((attr = element.attribute("mime")) == NATIVE_MIMETYPE) {
00403 if ((name = element.attribute("name")).isNull())
00404 return 0;
00405 if ((attr = element.attribute("width")).isNull())
00406 return 0;
00407 width = attr.toInt();
00408 if ((attr = element.attribute("height")).isNull())
00409 return 0;
00410 height = attr.toInt();
00411
00412 description = element.attribute("description");
00413
00414 if ((attr = element.attribute("x-res")).isNull())
00415 xres = 100.0;
00416 xres = attr.toDouble();
00417
00418 if ((attr = element.attribute("y-res")).isNull())
00419 yres = 100.0;
00420 yres = attr.toDouble();
00421
00422 if ((colorspacename = element.attribute("colorspacename")).isNull())
00423 {
00424
00425
00426
00427 colorspacename = "RGBA";
00428 }
00429
00430
00431 if (colorspacename == "Grayscale + Alpha")
00432 colorspacename = "GRAYA";
00433
00434 if ((profileProductName = element.attribute("profile")).isNull()) {
00435
00436 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(colorspacename,"");
00437 }
00438 else {
00439 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(colorspacename, profileProductName);
00440 }
00441
00442 if (cs == 0) {
00443 kdWarning(DBG_AREA_FILE) << "Could not open colorspace\n";
00444 return 0;
00445 }
00446
00447 img = new KisImage(this, width, height, cs, name);
00448 img->blockSignals(true);
00449 Q_CHECK_PTR(img);
00450 connect( img, SIGNAL( sigImageModified() ), this, SLOT( slotImageUpdated() ));
00451 img->setDescription(description);
00452 img->setResolution(xres, yres);
00453
00454 loadLayers(element, img, img->rootLayer().data());
00455
00456 }
00457
00458 img->notifyImageLoaded();
00459
00460 return img;
00461 }
00462
00463 void KisDoc::loadLayers(const QDomElement& element, KisImageSP img, KisGroupLayerSP parent)
00464 {
00465 QDomNode node = element.firstChild();
00466 QDomNode child;
00467
00468 if(!node.isNull())
00469 {
00470 if (node.isElement()) {
00471 if (node.nodeName() == "LAYERS") {
00472 for (child = node.firstChild(); !child.isNull(); child = child.nextSibling()) {
00473 KisLayerSP layer = loadLayer(child.toElement(), img);
00474
00475 if (!layer) {
00476 kdWarning(DBG_AREA_FILE) << "Could not load layer\n";
00477 }
00478 else {
00479 img->nextLayerName();
00480 img->addLayer(layer, parent, 0);
00481 }
00482 }
00483 }
00484 }
00485 }
00486 }
00487
00488 KisLayerSP KisDoc::loadLayer(const QDomElement& element, KisImageSP img)
00489 {
00490
00491
00492
00493
00494 QString attr;
00495 QString name;
00496 Q_INT32 x;
00497 Q_INT32 y;
00498 Q_INT32 opacity;
00499 bool visible;
00500 bool locked;
00501
00502 if ((name = element.attribute("name")).isNull())
00503 return 0;
00504
00505 if ((attr = element.attribute("x")).isNull())
00506 return 0;
00507 x = attr.toInt();
00508
00509 if ((attr = element.attribute("y")).isNull())
00510 return 0;
00511
00512 y = attr.toInt();
00513
00514 if ((attr = element.attribute("opacity")).isNull())
00515 return 0;
00516
00517 if ((opacity = attr.toInt()) < 0 || opacity > Q_UINT8_MAX)
00518 opacity = OPACITY_OPAQUE;
00519
00520
00521 QString compositeOpName = element.attribute("compositeop");
00522 KisCompositeOp compositeOp;
00523
00524 if (compositeOpName.isNull()) {
00525 compositeOp = COMPOSITE_OVER;
00526 } else {
00527 compositeOp = KisCompositeOp(compositeOpName);
00528 }
00529
00530 if (!compositeOp.isValid()) {
00531 return 0;
00532 }
00533
00534 if ((attr = element.attribute("visible")).isNull())
00535 attr = "1";
00536
00537 visible = attr == "0" ? false : true;
00538
00539 if ((attr = element.attribute("locked")).isNull())
00540 attr = "0";
00541
00542 locked = attr == "0" ? false : true;
00543
00544
00545 if ((attr = element.attribute("layertype")).isNull())
00546 return loadPaintLayer(element, img, name, x, y, opacity, visible, locked, compositeOp) ;
00547
00548 if(attr == "paintlayer")
00549 return loadPaintLayer(element, img, name, x, y, opacity, visible, locked, compositeOp);
00550
00551 if(attr == "grouplayer")
00552 return loadGroupLayer(element, img, name, x, y, opacity, visible, locked, compositeOp).data();
00553
00554 if(attr == "adjustmentlayer")
00555 return loadAdjustmentLayer(element, img, name, x, y, opacity, visible, locked, compositeOp).data();
00556
00557 if(attr == "partlayer")
00558 return loadPartLayer(element, img, name, x, y, opacity, visible, locked, compositeOp).data();
00559
00560 kdWarning(DBG_AREA_FILE) << "Specified layertype is not recognised\n";
00561 return 0;
00562 }
00563
00564
00565 KisLayerSP KisDoc::loadPaintLayer(const QDomElement& element, KisImageSP img,
00566 QString name, Q_INT32 x, Q_INT32 y,
00567 Q_INT32 opacity, bool visible, bool locked, KisCompositeOp compositeOp)
00568 {
00569 QString attr;
00570 KisPaintLayerSP layer;
00571 KisColorSpace * cs;
00572
00573 QString colorspacename;
00574 QString profileProductName;
00575
00576 if ((colorspacename = element.attribute("colorspacename")).isNull())
00577 cs = img->colorSpace();
00578 else
00579
00580 cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(colorspacename,"");
00581
00582 layer = new KisPaintLayer(img, name, opacity, cs);
00583 Q_CHECK_PTR(layer);
00584
00585 layer->setCompositeOp(compositeOp);
00586 layer->setVisible(visible);
00587 layer->setLocked(locked);
00588 layer->setX(x);
00589 layer->setY(y);
00590
00591 if ((element.attribute("filename")).isNull())
00592 m_layerFilenames[layer.data()] = name;
00593 else
00594 m_layerFilenames[layer.data()] = QString(element.attribute("filename"));
00595
00596
00597 for( QDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling() )
00598 {
00599 QDomElement e = node.toElement();
00600 if ( !e.isNull() && e.tagName() == "ExifInfo" )
00601 {
00602 layer->paintDevice()->exifInfo()->load(e);
00603 }
00604 }
00605 return layer.data();
00606 }
00607
00608 KisGroupLayerSP KisDoc::loadGroupLayer(const QDomElement& element, KisImageSP img,
00609 QString name, Q_INT32 x, Q_INT32 y, Q_INT32 opacity, bool visible, bool locked,
00610 KisCompositeOp compositeOp)
00611 {
00612 QString attr;
00613 KisGroupLayerSP layer;
00614
00615 layer = new KisGroupLayer(img, name, opacity);
00616 Q_CHECK_PTR(layer);
00617
00618 layer->setCompositeOp(compositeOp);
00619 layer->setVisible(visible);
00620 layer->setLocked(locked);
00621 layer->setX(x);
00622 layer->setY(y);
00623
00624 loadLayers(element, img, layer);
00625
00626 return layer;
00627 }
00628
00629 KisAdjustmentLayerSP KisDoc::loadAdjustmentLayer(const QDomElement& element, KisImageSP img,
00630 QString name, Q_INT32 x, Q_INT32 y, Q_INT32 opacity, bool visible, bool locked,
00631 KisCompositeOp compositeOp)
00632 {
00633 QString attr;
00634 KisAdjustmentLayerSP layer;
00635 QString filtername;
00636
00637 if ((filtername = element.attribute("filtername")).isNull()) {
00638
00639 kdWarning(DBG_AREA_FILE) << "No filter in adjustment layer" << endl;
00640 return 0;
00641 }
00642
00643 KisFilter * f = KisFilterRegistry::instance()->get(filtername);
00644 if (!f) {
00645 kdWarning(DBG_AREA_FILE) << "No filter for filtername " << filtername << "\n";
00646 return 0;
00647 }
00648
00649 KisFilterConfiguration * kfc = f->configuration();
00650
00651
00652 layer = new KisAdjustmentLayer(img, name, kfc, 0);
00653 Q_CHECK_PTR(layer);
00654
00655 layer->setCompositeOp(compositeOp);
00656 layer->setVisible(visible);
00657 layer->setLocked(locked);
00658 layer->setX(x);
00659 layer->setY(y);
00660 layer->setOpacity(opacity);
00661
00662 if ((element.attribute("filename")).isNull())
00663 m_layerFilenames[layer.data()] = name;
00664 else
00665 m_layerFilenames[layer.data()] = QString(element.attribute("filename"));
00666
00667 return layer;
00668 }
00669
00670 KisPartLayerSP KisDoc::loadPartLayer(const QDomElement& element, KisImageSP img,
00671 QString name, Q_INT32 , Q_INT32 , Q_INT32 opacity,
00672 bool visible, bool locked,
00673 KisCompositeOp compositeOp) {
00674 KisChildDoc* child = new KisChildDoc(this);
00675 QString filename(element.attribute("filename"));
00676 QDomElement partElement = element.namedItem("object").toElement();
00677
00678 if (partElement.isNull()) {
00679 kdWarning() << "loadPartLayer failed with partElement isNull" << endl;
00680 return 0;
00681 }
00682
00683 child->load(partElement);
00684 insertChild(child);
00685
00686 KisPartLayerSP layer = new KisPartLayerImpl(img, child);
00687 Q_CHECK_PTR(layer);
00688
00689 layer->setCompositeOp(compositeOp);
00690 layer->setVisible(visible);
00691 layer->setLocked(locked);
00692 layer->setOpacity(opacity);
00693 layer->setName(name);
00694
00695 return layer;
00696 }
00697
00698 bool KisDoc::completeSaving(KoStore *store)
00699 {
00700 QString uri = url().url();
00701 QString location;
00702 bool external = isStoredExtern();
00703 Q_INT32 totalSteps = 0;
00704
00705 if (!m_currentImage) return false;
00706
00707 totalSteps = (m_currentImage)->nlayers();
00708
00709
00710 setIOSteps(totalSteps + 1);
00711
00712
00713 Q_UINT32 count=0;
00714 KisSaveVisitor visitor(m_currentImage, store, count);
00715
00716 if(external)
00717 visitor.setExternalUri(uri);
00718
00719 m_currentImage->rootLayer()->accept(visitor);
00720
00721
00722
00723
00724
00725 KisAnnotationSP annotation = (m_currentImage)->annotation("exif");
00726 if (annotation) {
00727 location = external ? QString::null : uri;
00728 location += (m_currentImage)->name() + "/annotations/exif";
00729 if (store->open(location)) {
00730 store->write(annotation->annotation());
00731 store->close();
00732 }
00733 }
00734 if (m_currentImage->getProfile()) {
00735 annotation = m_currentImage->getProfile()->annotation();
00736
00737 if (annotation) {
00738 location = external ? QString::null : uri;
00739 location += m_currentImage->name() + "/annotations/icc";
00740 if (store->open(location)) {
00741 store->write(annotation->annotation());
00742 store->close();
00743 }
00744 }
00745 }
00746
00747 IODone();
00748 return true;
00749 }
00750
00751 bool KisDoc::completeLoading(KoStore *store)
00752 {
00753 QString uri = url().url();
00754 QString location;
00755 bool external = isStoredExtern();
00756 Q_INT32 totalSteps = 0;
00757
00758 totalSteps = (m_currentImage)->nlayers();
00759
00760 setIOSteps(totalSteps);
00761
00762
00763 KisLoadVisitor visitor(m_currentImage, store, m_layerFilenames);
00764
00765 if(external)
00766 visitor.setExternalUri(uri);
00767
00768 m_currentImage->rootLayer()->accept(visitor);
00769
00770
00771
00772 location = external ? QString::null : uri;
00773 location += (m_currentImage)->name() + "/annotations/exif";
00774 if (store->hasFile(location)) {
00775 QByteArray data;
00776 store->open(location);
00777 data = store->read(store->size());
00778 store->close();
00779 (m_currentImage)->addAnnotation(new KisAnnotation("exif", "", data));
00780 }
00781
00782 location = external ? QString::null : uri;
00783 location += (m_currentImage)->name() + "/annotations/icc";
00784 if (store->hasFile(location)) {
00785 QByteArray data;
00786 store->open(location);
00787 data = store->read(store->size());
00788 store->close();
00789 (m_currentImage)->setProfile(new KisProfile(data));
00790 }
00791
00792 IODone();
00793
00794 setModified( false );
00795 setUndo(true);
00796 return true;
00797 }
00798
00799 QWidget* KisDoc::createCustomDocumentWidget(QWidget *parent)
00800 {
00801
00802 KisConfig cfg;
00803
00804 int w = cfg.defImgWidth();
00805 int h = cfg.defImgHeight();
00806
00807 QSize sz = KisClipboard::instance()->clipSize();
00808 if (sz.isValid() && sz.width() != 0 && sz.height() != 0) {
00809 w = sz.width();
00810 h = sz.height();
00811 }
00812 return new KisCustomImageWidget(parent, this, w, h, cfg.defImgResolution(), cfg.workingColorSpace(),"unnamed");
00813 }
00814
00815
00816 KoDocument* KisDoc::hitTest(const QPoint &pos, const QWMatrix& matrix) {
00817 KoDocument* doc = super::hitTest(pos, matrix);
00818 if (doc && doc != this) {
00819
00820
00821 KisPartLayerImpl* partLayer
00822 = dynamic_cast<KisPartLayerImpl*>(currentImage()->activeLayer().data());
00823
00824 if (!partLayer)
00825 return this;
00826
00827 if (doc == partLayer->childDoc()->document()) {
00828 return doc;
00829 }
00830 return this;
00831 }
00832 return doc;
00833 }
00834
00835 void KisDoc::renameImage(const QString& oldName, const QString& newName)
00836 {
00837 (m_currentImage)->setName(newName);
00838
00839 if (undo())
00840 addCommand(new KisCommandImageMv(this, this, newName, oldName));
00841 }
00842
00843
00844 KisImageSP KisDoc::newImage(const QString& name, Q_INT32 width, Q_INT32 height, KisColorSpace * colorstrategy)
00845 {
00846 if (!init())
00847 return 0;
00848
00849 setUndo(false);
00850
00851 KisImageSP img = new KisImage(this, width, height, colorstrategy, name);
00852 Q_CHECK_PTR(img);
00853 connect( img, SIGNAL( sigImageModified() ), this, SLOT( slotImageUpdated() ));
00854
00855 KisPaintLayer *layer = new KisPaintLayer(img, img->nextLayerName(), OPACITY_OPAQUE,colorstrategy);
00856 Q_CHECK_PTR(layer);
00857
00858 KisColorSpace * cs = KisMetaRegistry::instance()->csRegistry()->getRGB8();
00859 KisFillPainter painter;
00860
00861 painter.begin(layer->paintDevice());
00862 painter.fillRect(0, 0, width, height, KisColor(Qt::white, cs), OPACITY_OPAQUE);
00863 painter.end();
00864
00865 img->addLayer(layer, img->rootLayer(), 0);
00866 img->activate(layer);
00867
00868 m_currentImage = img;
00869
00870 setUndo(true);
00871
00872 return img;
00873 }
00874
00875 bool KisDoc::newImage(const QString& name, Q_INT32 width, Q_INT32 height, KisColorSpace * cs, const KisColor &bgColor, const QString &imgDescription, const double imgResolution)
00876 {
00877 if (!init())
00878 return false;
00879
00880 KisConfig cfg;
00881
00882 Q_UINT8 opacity = OPACITY_OPAQUE;
00883 KisImageSP img;
00884 KisPaintLayer *layer;
00885
00886 if (!cs) return false;
00887
00888 setUndo(false);
00889
00890 img = new KisImage(this, width, height, cs, name);
00891 Q_CHECK_PTR(img);
00892 connect( img, SIGNAL( sigImageModified() ), this, SLOT( slotImageUpdated() ));
00893 img->setResolution(imgResolution, imgResolution);
00894 img->setDescription(imgDescription);
00895 img->setProfile(cs->getProfile());
00896
00897 layer = new KisPaintLayer(img, img->nextLayerName(), OPACITY_OPAQUE, cs);
00898 Q_CHECK_PTR(layer);
00899
00900 KisFillPainter painter;
00901 painter.begin(layer->paintDevice());
00902 painter.fillRect(0, 0, width, height, bgColor, opacity);
00903 painter.end();
00904
00905 QValueVector<KisPaintDeviceAction *> actions = KisMetaRegistry::instance() ->
00906 csRegistry()->paintDeviceActionsFor(cs);
00907 for (uint i = 0; i < actions.count(); i++)
00908 actions.at(i)->act(layer->paintDevice(), img->width(), img->height());
00909
00910 img->setBackgroundColor(bgColor);
00911 img->addLayer(layer, img->rootLayer(), 0);
00912 img->activate(layer);
00913
00914 m_currentImage = img;
00915
00916 cfg.defImgWidth(width);
00917 cfg.defImgHeight(height);
00918 cfg.defImgResolution(imgResolution);
00919
00920 setUndo(true);
00921
00922 return true;
00923 }
00924
00925 KoView* KisDoc::createViewInstance(QWidget* parent, const char *name)
00926 {
00927 KisView * v = new KisView(this, this, parent, name);
00928 Q_CHECK_PTR(v);
00929
00930 return v;
00931 }
00932
00933 void KisDoc::paintContent(QPainter& painter, const QRect& rc, bool transparent, double zoomX, double zoomY)
00934 {
00935 KisConfig cfg;
00936 QString monitorProfileName = cfg.monitorProfile();
00937 KisProfile * profile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName);
00938 painter.scale(zoomX, zoomY);
00939 QRect rect = rc & m_currentImage->bounds();
00940 KisImage::PaintFlags paintFlags;
00941 if (transparent) {
00942 paintFlags = KisImage::PAINT_SELECTION;
00943 } else {
00944 paintFlags = (KisImage::PaintFlags)(KisImage::PAINT_BACKGROUND|KisImage::PAINT_SELECTION);
00945 }
00946
00947 paintFlags = (KisImage::PaintFlags)(paintFlags | KisImage::PAINT_EMBEDDED_RECT);
00948
00949 m_currentImage->renderToPainter(rect.left(), rect.top(), rect.right(), rect.bottom(), painter, profile, paintFlags);
00950 }
00951
00952 void KisDoc::slotImageUpdated()
00953 {
00954 emit docUpdated();
00955 setModified(true);
00956 }
00957
00958 void KisDoc::slotImageUpdated(const QRect& rect)
00959 {
00960 emit docUpdated(rect);
00961 }
00962
00963 void KisDoc::beginMacro(const QString& macroName)
00964 {
00965 if (m_undo) {
00966 if (m_macroNestDepth == 0) {
00967 Q_ASSERT(m_currentMacro == 0);
00968 m_currentMacro = new KMacroCommand(macroName);
00969 Q_CHECK_PTR(m_currentMacro);
00970 }
00971
00972 m_macroNestDepth++;
00973 }
00974 }
00975
00976 void KisDoc::endMacro()
00977 {
00978 if (m_undo) {
00979 Q_ASSERT(m_macroNestDepth > 0);
00980 if (m_macroNestDepth > 0) {
00981 m_macroNestDepth--;
00982
00983 if (m_macroNestDepth == 0) {
00984 Q_ASSERT(m_currentMacro != 0);
00985
00986 m_cmdHistory->addCommand(m_currentMacro, false);
00987 m_currentMacro = 0;
00988 emit sigCommandExecuted();
00989 }
00990 }
00991 }
00992 }
00993
00994 void KisDoc::setCommandHistoryListener(const KisCommandHistoryListener * l)
00995 {
00996
00997 m_undoListeners.removeRef(l);
00998 m_undoListeners.append(l);
00999 }
01000
01001 void KisDoc::removeCommandHistoryListener(const KisCommandHistoryListener * l)
01002 {
01003 m_undoListeners.removeRef(l);
01004 }
01005
01006 KCommand * KisDoc::presentCommand()
01007 {
01008 return m_cmdHistory->presentCommand();
01009 }
01010
01011 void KisDoc::addCommand(KCommand *cmd)
01012 {
01013 Q_ASSERT(cmd);
01014
01015 KisCommandHistoryListener* l = 0;
01016
01017 for (l = m_undoListeners.first(); l; l = m_undoListeners.next()) {
01018 l->notifyCommandAdded(cmd);
01019 }
01020
01021 setModified(true);
01022
01023 if (m_undo) {
01024 if (m_currentMacro)
01025 m_currentMacro->addCommand(cmd);
01026 else {
01027 m_cmdHistory->addCommand(cmd, false);
01028 emit sigCommandExecuted();
01029 }
01030 } else {
01031 kdDebug() << "Deleting command\n";
01032 delete cmd;
01033 }
01034 }
01035
01036 void KisDoc::setUndo(bool undo)
01037 {
01038 m_undo = undo;
01039 if (m_undo && m_cmdHistory->undoLimit() == 50 ) {
01040 KisConfig cfg;
01041 setUndoLimit( cfg.defUndoLimit() );
01042 }
01043 }
01044
01045 Q_INT32 KisDoc::undoLimit() const
01046 {
01047 return m_cmdHistory->undoLimit();
01048 }
01049
01050 void KisDoc::setUndoLimit(Q_INT32 limit)
01051 {
01052 m_cmdHistory->setUndoLimit(limit);
01053 }
01054
01055 Q_INT32 KisDoc::redoLimit() const
01056 {
01057 return m_cmdHistory->redoLimit();
01058 }
01059
01060 void KisDoc::setRedoLimit(Q_INT32 limit)
01061 {
01062 m_cmdHistory->setRedoLimit(limit);
01063 }
01064
01065 void KisDoc::slotDocumentRestored()
01066 {
01067 setModified(false);
01068 }
01069
01070 void KisDoc::slotCommandExecuted(KCommand *command)
01071 {
01072 setModified(true);
01073 emit sigCommandExecuted();
01074
01075 KisCommandHistoryListener* l = 0;
01076
01077 for (l = m_undoListeners.first(); l; l = m_undoListeners.next()) {
01078 l->notifyCommandExecuted(command);
01079 }
01080
01081 }
01082
01083 void KisDoc::slotUpdate(KisImageSP, Q_UINT32 x, Q_UINT32 y, Q_UINT32 w, Q_UINT32 h)
01084 {
01085 QRect rc(x, y, w, h);
01086
01087 emit docUpdated(rc);
01088 }
01089
01090 bool KisDoc::undo() const
01091 {
01092 return m_undo;
01093 }
01094
01095 void KisDoc::setIOSteps(Q_INT32 nsteps)
01096 {
01097 m_ioProgressTotalSteps = nsteps * 100;
01098 m_ioProgressBase = 0;
01099 emitProgress(0);
01100 }
01101
01102 void KisDoc::IOCompletedStep()
01103 {
01104 m_ioProgressBase += 100;
01105 }
01106
01107 void KisDoc::IODone()
01108 {
01109 emitProgress(-1);
01110 }
01111
01112 void KisDoc::slotIOProgress(Q_INT8 percentage)
01113 {
01114 KApplication *app = KApplication::kApplication();
01115
01116 Q_ASSERT(app);
01117
01118 if (app->hasPendingEvents())
01119 app->processEvents();
01120
01121 int totalPercentage = ((m_ioProgressBase + percentage) * 100) / m_ioProgressTotalSteps;
01122
01123 emitProgress(totalPercentage);
01124 }
01125
01126 KisChildDoc * KisDoc::createChildDoc( const QRect & rect, KoDocument* childDoc )
01127 {
01128 KisChildDoc * ch = new KisChildDoc( this, rect, childDoc );
01129 insertChild( ch );
01130 ch->document()->setStoreInternal(true);
01131 return ch;
01132 }
01133
01134 void KisDoc::prepareForImport()
01135 {
01136 if (m_nserver == 0)
01137 init();
01138 setUndo(false);
01139 }
01140
01141 KisImageSP KisDoc::currentImage()
01142 {
01143 return m_currentImage;
01144 }
01145
01146 void KisDoc::setCurrentImage(KisImageSP image)
01147 {
01148 m_currentImage = image;
01149 setUndo(true);
01150 image->notifyImageLoaded();
01151 emit loadingFinished();
01152 }
01153
01154 void KisDoc::initEmpty()
01155 {
01156 KisConfig cfg;
01157 KisColorSpace * rgb = KisMetaRegistry::instance()->csRegistry()->getRGB8();
01158 newImage("", cfg.defImgWidth(), cfg.defImgHeight(), rgb);
01159 }
01160
01161 #include "kis_doc.moc"
01162