00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <kdebug.h>
00021 #include <qimage.h>
00022
00023 #include "kis_debug_areas.h"
00024 #include "kis_group_layer.h"
00025 #include "kis_image.h"
00026 #include "kis_layer.h"
00027 #include "kis_painter.h"
00028 #include "kis_undo_adapter.h"
00029
00030 namespace {
00031
00032 class KisLayerCommand : public KNamedCommand {
00033 typedef KNamedCommand super;
00034
00035 public:
00036 KisLayerCommand(const QString& name, KisLayerSP layer);
00037 virtual ~KisLayerCommand() {}
00038
00039 virtual void execute() = 0;
00040 virtual void unexecute() = 0;
00041
00042 protected:
00043 void setUndo(bool undo);
00044
00045 KisLayerSP m_layer;
00046 };
00047
00048 KisLayerCommand::KisLayerCommand(const QString& name, KisLayerSP layer) :
00049 super(name), m_layer(layer)
00050 {
00051 }
00052
00053 void KisLayerCommand::setUndo(bool undo)
00054 {
00055 if (m_layer->undoAdapter()) {
00056 m_layer->undoAdapter()->setUndo(undo);
00057 }
00058 }
00059
00060 class KisLayerLockedCommand : public KisLayerCommand {
00061 typedef KisLayerCommand super;
00062
00063 public:
00064 KisLayerLockedCommand(KisLayerSP layer, bool newLocked);
00065
00066 virtual void execute();
00067 virtual void unexecute();
00068
00069 private:
00070 bool m_newLocked;
00071 };
00072
00073 KisLayerLockedCommand::KisLayerLockedCommand(KisLayerSP layer, bool newLocked) :
00074 super(i18n("Lock Layer"), layer)
00075 {
00076 m_newLocked = newLocked;
00077 }
00078
00079 void KisLayerLockedCommand::execute()
00080 {
00081 setUndo(false);
00082 m_layer->setLocked(m_newLocked);
00083 setUndo(true);
00084 }
00085
00086 void KisLayerLockedCommand::unexecute()
00087 {
00088 setUndo(false);
00089 m_layer->setLocked(!m_newLocked);
00090 setUndo(true);
00091 }
00092
00093 class KisLayerOpacityCommand : public KisLayerCommand {
00094 typedef KisLayerCommand super;
00095
00096 public:
00097 KisLayerOpacityCommand(KisLayerSP layer, Q_UINT8 oldOpacity, Q_UINT8 newOpacity);
00098
00099 virtual void execute();
00100 virtual void unexecute();
00101
00102 private:
00103 Q_UINT8 m_oldOpacity;
00104 Q_UINT8 m_newOpacity;
00105 };
00106
00107 KisLayerOpacityCommand::KisLayerOpacityCommand(KisLayerSP layer, Q_UINT8 oldOpacity, Q_UINT8 newOpacity) :
00108 super(i18n("Layer Opacity"), layer)
00109 {
00110 m_oldOpacity = oldOpacity;
00111 m_newOpacity = newOpacity;
00112 }
00113
00114 void KisLayerOpacityCommand::execute()
00115 {
00116 setUndo(false);
00117 m_layer->setOpacity(m_newOpacity);
00118 setUndo(true);
00119 }
00120
00121 void KisLayerOpacityCommand::unexecute()
00122 {
00123 setUndo(false);
00124 m_layer->setOpacity(m_oldOpacity);
00125 setUndo(true);
00126 }
00127
00128 class KisLayerVisibilityCommand : public KisLayerCommand {
00129 typedef KisLayerCommand super;
00130
00131 public:
00132 KisLayerVisibilityCommand(KisLayerSP layer, bool newVisibility);
00133
00134 virtual void execute();
00135 virtual void unexecute();
00136
00137 private:
00138 bool m_newVisibility;
00139 };
00140
00141 KisLayerVisibilityCommand::KisLayerVisibilityCommand(KisLayerSP layer, bool newVisibility) :
00142 super(i18n("Layer Visibility"), layer)
00143 {
00144 m_newVisibility = newVisibility;
00145 }
00146
00147 void KisLayerVisibilityCommand::execute()
00148 {
00149 setUndo(false);
00150 m_layer->setVisible(m_newVisibility);
00151 setUndo(true);
00152 }
00153
00154 void KisLayerVisibilityCommand::unexecute()
00155 {
00156 setUndo(false);
00157 m_layer->setVisible(!m_newVisibility);
00158 setUndo(true);
00159 }
00160
00161 class KisLayerCompositeOpCommand : public KisLayerCommand {
00162 typedef KisLayerCommand super;
00163
00164 public:
00165 KisLayerCompositeOpCommand(KisLayerSP layer, const KisCompositeOp& oldCompositeOp, const KisCompositeOp& newCompositeOp);
00166
00167 virtual void execute();
00168 virtual void unexecute();
00169
00170 private:
00171 KisCompositeOp m_oldCompositeOp;
00172 KisCompositeOp m_newCompositeOp;
00173 };
00174
00175 KisLayerCompositeOpCommand::KisLayerCompositeOpCommand(KisLayerSP layer, const KisCompositeOp& oldCompositeOp,
00176 const KisCompositeOp& newCompositeOp) :
00177 super(i18n("Layer Composite Mode"), layer)
00178 {
00179 m_oldCompositeOp = oldCompositeOp;
00180 m_newCompositeOp = newCompositeOp;
00181 }
00182
00183 void KisLayerCompositeOpCommand::execute()
00184 {
00185 setUndo(false);
00186 m_layer->setCompositeOp(m_newCompositeOp);
00187 setUndo(true);
00188 }
00189
00190 void KisLayerCompositeOpCommand::unexecute()
00191 {
00192 setUndo(false);
00193 m_layer->setCompositeOp(m_oldCompositeOp);
00194 setUndo(true);
00195 }
00196
00197 class KisLayerOffsetCommand : public KNamedCommand {
00198 typedef KNamedCommand super;
00199
00200 public:
00201 KisLayerOffsetCommand(KisLayerSP layer, const QPoint& oldpos, const QPoint& newpos);
00202 virtual ~KisLayerOffsetCommand();
00203
00204 virtual void execute();
00205 virtual void unexecute();
00206
00207 private:
00208 void moveTo(const QPoint& pos);
00209
00210 private:
00211 KisLayerSP m_layer;
00212 QRect m_updateRect;
00213 QPoint m_oldPos;
00214 QPoint m_newPos;
00215 };
00216
00217 KisLayerOffsetCommand::KisLayerOffsetCommand(KisLayerSP layer, const QPoint& oldpos, const QPoint& newpos) :
00218 super(i18n("Move Layer"))
00219 {
00220 m_layer = layer;
00221 m_oldPos = oldpos;
00222 m_newPos = newpos;
00223
00224 QRect currentBounds = m_layer->exactBounds();
00225 QRect oldBounds = currentBounds;
00226 oldBounds.moveBy(oldpos.x() - newpos.x(), oldpos.y() - newpos.y());
00227
00228 m_updateRect = currentBounds | oldBounds;
00229 }
00230
00231 KisLayerOffsetCommand::~KisLayerOffsetCommand()
00232 {
00233 }
00234
00235 void KisLayerOffsetCommand::execute()
00236 {
00237 moveTo(m_newPos);
00238 }
00239
00240 void KisLayerOffsetCommand::unexecute()
00241 {
00242 moveTo(m_oldPos);
00243 }
00244
00245 void KisLayerOffsetCommand::moveTo(const QPoint& pos)
00246 {
00247 if (m_layer->undoAdapter()) {
00248 m_layer->undoAdapter()->setUndo(false);
00249 }
00250
00251 m_layer->setX(pos.x());
00252 m_layer->setY(pos.y());
00253
00254 m_layer->setDirty(m_updateRect);
00255
00256 if (m_layer->undoAdapter()) {
00257 m_layer->undoAdapter()->setUndo(true);
00258 }
00259 }
00260 }
00261
00262 static int getID()
00263 {
00264 static int id = 1;
00265 return id++;
00266 }
00267
00268
00269 KisLayer::KisLayer(KisImage *img, const QString &name, Q_UINT8 opacity) :
00270 QObject(0, name.latin1()),
00271 KShared(),
00272 m_id(getID()),
00273 m_index(-1),
00274 m_opacity(opacity),
00275 m_locked(false),
00276 m_visible(true),
00277 m_temporary(false),
00278 m_name(name),
00279 m_parent(0),
00280 m_image(img),
00281 m_compositeOp(COMPOSITE_OVER)
00282 {
00283 }
00284
00285 KisLayer::KisLayer(const KisLayer& rhs) :
00286 QObject(),
00287 KShared(rhs)
00288 {
00289 if (this != &rhs) {
00290 m_id = getID();
00291 m_index = -1;
00292 m_opacity = rhs.m_opacity;
00293 m_locked = rhs.m_locked;
00294 m_visible = rhs.m_visible;
00295 m_temporary = rhs.m_temporary;
00296 m_dirtyRect = rhs.m_dirtyRect;
00297 m_name = rhs.m_name;
00298 m_image = rhs.m_image;
00299 m_parent = 0;
00300 m_compositeOp = rhs.m_compositeOp;
00301 }
00302 }
00303
00304 KisLayer::~KisLayer()
00305 {
00306 }
00307
00308 void KisLayer::setClean(const QRect & rect)
00309 {
00310 if (m_dirtyRect.isValid() && rect.isValid()) {
00311
00312
00313
00314
00315 m_dirtyRect = QRect();
00316 }
00317
00318 }
00319
00320 bool KisLayer::dirty()
00321 {
00322 return m_dirtyRect.isValid();
00323 }
00324
00325
00326 bool KisLayer::dirty(const QRect & rc)
00327 {
00328 if (!m_dirtyRect.isValid() || !rc.isValid()) return false;
00329
00330 return rc.intersects(m_dirtyRect);
00331 }
00332
00333 QRect KisLayer::dirtyRect() const
00334 {
00335 return m_dirtyRect;
00336 }
00337
00338 void KisLayer::setDirty(bool propagate)
00339 {
00340 QRect rc = extent();
00341
00342 if (rc.isValid()) m_dirtyRect = rc;
00343
00344
00345 if (propagate && m_parent && rc.isValid()) m_parent->setDirty(m_dirtyRect);
00346
00347 if (m_image && rc.isValid()) {
00348 m_image->notifyLayerUpdated(this, rc);
00349 }
00350 }
00351
00352 void KisLayer::setDirty(const QRect & rc, bool propagate)
00353 {
00354
00355
00356 if (rc.isValid())
00357 m_dirtyRect |= rc;
00358
00359 if (propagate && m_parent && m_dirtyRect.isValid())
00360 m_parent->setDirty(m_dirtyRect);
00361
00362 if (m_image && rc.isValid()) {
00363 m_image->notifyLayerUpdated(this, rc);
00364 }
00365 }
00366
00367 KisGroupLayerSP KisLayer::parent() const
00368 {
00369 return m_parent;
00370 }
00371
00372 KisLayerSP KisLayer::prevSibling() const
00373 {
00374 if (!parent())
00375 return 0;
00376 return parent()->at(index() - 1);
00377 }
00378
00379 KisLayerSP KisLayer::nextSibling() const
00380 {
00381 if (!parent())
00382 return 0;
00383 return parent()->at(index() + 1);
00384 }
00385
00386 int KisLayer::index() const
00387 {
00388 return m_index;
00389 }
00390
00391 void KisLayer::setIndex(int i)
00392 {
00393 if (!parent())
00394 return;
00395 parent()->setIndex(this, i);
00396 }
00397
00398 KisLayerSP KisLayer::findLayer(const QString& n) const
00399 {
00400 if (name() == n)
00401 return const_cast<KisLayer*>(this);
00402 for (KisLayerSP layer = firstChild(); layer; layer = layer->nextSibling())
00403 if (KisLayerSP found = layer->findLayer(n))
00404 return found;
00405 return 0;
00406 }
00407
00408 KisLayerSP KisLayer::findLayer(int i) const
00409 {
00410 if (id() == i)
00411 return const_cast<KisLayer*>(this);
00412 for (KisLayerSP layer = firstChild(); layer; layer = layer->nextSibling())
00413 if (KisLayerSP found = layer->findLayer(i))
00414 return found;
00415 return 0;
00416 }
00417
00418 int KisLayer::numLayers(int flags) const
00419 {
00420 int num = 0;
00421 if (matchesFlags(flags)) num++;
00422 for (KisLayerSP layer = firstChild(); layer; layer = layer->nextSibling())
00423 num += layer->numLayers(flags);
00424 return num;
00425 }
00426
00427 bool KisLayer::matchesFlags(int flags) const
00428 {
00429 if ((flags & Visible) && !visible())
00430 return false;
00431 if ((flags & Hidden) && visible())
00432 return false;
00433 if ((flags & Locked) && !locked())
00434 return false;
00435 if ((flags & Unlocked) && locked())
00436 return false;
00437 return true;
00438 }
00439
00440 Q_UINT8 KisLayer::opacity() const
00441 {
00442 return m_opacity;
00443 }
00444
00445 void KisLayer::setOpacity(Q_UINT8 val)
00446 {
00447 if (m_opacity != val)
00448 {
00449 m_opacity = val;
00450 setDirty();
00451 notifyPropertyChanged();
00452 }
00453 }
00454
00455 KNamedCommand *KisLayer::setOpacityCommand(Q_UINT8 newOpacity)
00456 {
00457 return new KisLayerOpacityCommand(this, opacity(), newOpacity);
00458 }
00459
00460 KNamedCommand *KisLayer::setOpacityCommand(Q_UINT8 prevOpacity, Q_UINT8 newOpacity)
00461 {
00462 return new KisLayerOpacityCommand(this, prevOpacity, newOpacity);
00463 }
00464
00465 const bool KisLayer::visible() const
00466 {
00467 return m_visible;
00468 }
00469
00470 void KisLayer::setVisible(bool v)
00471 {
00472 if (m_visible != v) {
00473
00474 m_visible = v;
00475 notifyPropertyChanged();
00476 setDirty();
00477
00478 if (undoAdapter() && undoAdapter()->undo()) {
00479 undoAdapter()->addCommand(setVisibleCommand(v));
00480 }
00481 }
00482 }
00483
00484 KNamedCommand *KisLayer::setVisibleCommand(bool newVisibility)
00485 {
00486 return new KisLayerVisibilityCommand(this, newVisibility);
00487 }
00488
00489 bool KisLayer::locked() const
00490 {
00491 return m_locked;
00492 }
00493
00494 void KisLayer::setLocked(bool l)
00495 {
00496 if (m_locked != l) {
00497 m_locked = l;
00498 notifyPropertyChanged();
00499
00500 if (undoAdapter() && undoAdapter()->undo()) {
00501 undoAdapter()->addCommand(setLockedCommand(l));
00502 }
00503 }
00504 }
00505
00506 bool KisLayer::temporary() const
00507 {
00508 return m_temporary;
00509 }
00510
00511 void KisLayer::setTemporary(bool t)
00512 {
00513 m_temporary = t;
00514 }
00515
00516 KNamedCommand *KisLayer::setLockedCommand(bool newLocked)
00517 {
00518 return new KisLayerLockedCommand(this, newLocked);
00519 }
00520
00521 QString KisLayer::name() const
00522 {
00523 return m_name;
00524 }
00525
00526 void KisLayer::setName(const QString& name)
00527 {
00528 if (!name.isEmpty() && m_name != name)
00529 {
00530 m_name = name;
00531 notifyPropertyChanged();
00532 }
00533 }
00534
00535 void KisLayer::setCompositeOp(const KisCompositeOp& compositeOp)
00536 {
00537 if (m_compositeOp != compositeOp)
00538 {
00539 m_compositeOp = compositeOp;
00540 notifyPropertyChanged();
00541 setDirty();
00542
00543 }
00544 }
00545
00546 KNamedCommand *KisLayer::setCompositeOpCommand(const KisCompositeOp& newCompositeOp)
00547 {
00548 return new KisLayerCompositeOpCommand(this, compositeOp(), newCompositeOp);
00549 }
00550
00551 KNamedCommand *KisLayer::moveCommand(QPoint oldPosition, QPoint newPosition)
00552 {
00553 return new KisLayerOffsetCommand(this, oldPosition, newPosition);
00554 }
00555
00556 KisUndoAdapter *KisLayer::undoAdapter() const
00557 {
00558 if (m_image) {
00559 return m_image->undoAdapter();
00560 }
00561 return 0;
00562 }
00563
00564 void KisLayer::paintMaskInactiveLayers(QImage &, Q_INT32, Q_INT32, Q_INT32, Q_INT32)
00565 {
00566 }
00567
00568 void KisLayer::paintSelection(QImage &, Q_INT32, Q_INT32, Q_INT32, Q_INT32)
00569 {
00570 }
00571
00572 void KisLayer::paintSelection(QImage &, const QRect&, const QSize&, const QSize&)
00573 {
00574 }
00575
00576 QImage KisLayer::createThumbnail(Q_INT32, Q_INT32)
00577 {
00578 return 0;
00579 }
00580
00581 void KisLayer::notifyPropertyChanged()
00582 {
00583 if(image() && !signalsBlocked())
00584 image()->notifyPropertyChanged(this);
00585 }
00586
00587 #include "kis_layer.moc"