| 26 | enum Op { Move, Copy }; |
| 27 | |
| 28 | static DocumentRange drop_range_op( |
| 29 | Document* doc, Op op, const DocumentRange& from, |
| 30 | DocumentRangePlace place, const DocumentRange& to) |
| 31 | { |
| 32 | if (place != kDocumentRangeBefore && |
| 33 | place != kDocumentRangeAfter) { |
| 34 | ASSERT(false); |
| 35 | throw std::invalid_argument("Invalid 'place' argument"); |
| 36 | } |
| 37 | |
| 38 | Sprite* sprite = doc->sprite(); |
| 39 | |
| 40 | // Check noop/trivial/do nothing cases, i.e., move a range to the same place. |
| 41 | // Also check invalid cases, like moving a Background layer. |
| 42 | switch (from.type()) { |
| 43 | case DocumentRange::kCels: |
| 44 | if (from == to) |
| 45 | return from; |
| 46 | break; |
| 47 | case DocumentRange::kFrames: |
| 48 | if (op == Move) { |
| 49 | if ((to.frameBegin() >= from.frameBegin() && to.frameEnd() <= from.frameEnd()) || |
| 50 | (place == kDocumentRangeBefore && to.frameBegin() == from.frameEnd()+1) || |
| 51 | (place == kDocumentRangeAfter && to.frameEnd() == from.frameBegin()-1)) |
| 52 | return from; |
| 53 | } |
| 54 | break; |
| 55 | case DocumentRange::kLayers: |
| 56 | if (op == Move) { |
| 57 | if ((to.layerBegin() >= from.layerBegin() && to.layerEnd() <= from.layerEnd()) || |
| 58 | (place == kDocumentRangeBefore && to.layerBegin() == from.layerEnd()+1) || |
| 59 | (place == kDocumentRangeAfter && to.layerEnd() == from.layerBegin()-1)) |
| 60 | return from; |
| 61 | |
| 62 | // We cannot move the background |
| 63 | for (LayerIndex i = from.layerBegin(); i <= from.layerEnd(); ++i) |
| 64 | if (sprite->indexToLayer(i)->isBackground()) |
| 65 | throw std::runtime_error("The background layer cannot be moved"); |
| 66 | } |
| 67 | |
| 68 | // Before background |
| 69 | if (place == kDocumentRangeBefore) { |
| 70 | Layer* background = sprite->indexToLayer(to.layerBegin()); |
| 71 | if (background && background->isBackground()) |
| 72 | throw std::runtime_error("You cannot move or copy something below the background layer"); |
| 73 | } |
| 74 | break; |
| 75 | } |
| 76 | |
| 77 | const char* undoLabel = NULL; |
| 78 | switch (op) { |
| 79 | case Move: undoLabel = "Move Range"; break; |
| 80 | case Copy: undoLabel = "Copy Range"; break; |
| 81 | default: |
| 82 | ASSERT(false); |
| 83 | throw std::invalid_argument("Invalid 'op' argument"); |
| 84 | } |
| 85 | DocumentRange resultRange; |
no test coverage detected