Relationship::Relationship(Canvas *canvas, const QDomElement& node, const QString& dunNs, bool no_undo) : shape(NULL), guide(NULL), guide2(NULL), distro(NULL), separation(NULL) { Q_UNUSED (dunNs) QString relTypeStr = node.attribute(x_relType); assert(!relTypeStr.isNull()); if (relTypeStr == x_alignment) { relType = REL_Align; type = (atypes) essentialProp<int>(node, x_alignmentPos); guide = dynamic_cast<Guideline *> (canvas->getItemByID( essentialProp<QString>(node, x_constraintID))); shape = dynamic_cast<ShapeObj *> (canvas->getItemByID( essentialProp<QString>(node, x_objOneID))); assert(shape); assert(guide); if (atypes_to_dirctn(type) != guide->get_dir()) { qWarning("Constraint relationship with wrong " "direction, adjusting..."); type = (atypes) (((int)type + 3) % 6); } if (dynamic_cast<Cluster *> (shape)) { qWarning("Ignoring cluster %d attached to guideline %d.", shape->internalId(), guide->internalId()); } else { activate(no_undo); } } else if (relTypeStr == x_distribution) { relType = REL_Distr; distro = dynamic_cast<Distribution *> (canvas->getItemByID( essentialProp<QString>(node, x_constraintID))); guide = dynamic_cast<Guideline *> (canvas->getItemByID( essentialProp<QString>(node, x_objOneID))); guide2 = dynamic_cast<Guideline *> (canvas->getItemByID( essentialProp<QString>(node, x_objTwoID))); assert(distro); assert(guide); assert(guide2); activate(no_undo); } else if (relTypeStr == x_separation) { relType = REL_Separ; separation = dynamic_cast<Separation *> (canvas->getItemByID( essentialProp<QString>(node, x_constraintID))); guide = dynamic_cast<Guideline *> (canvas->getItemByID( essentialProp<QString>(node, x_objOneID))); guide2 = dynamic_cast<Guideline *> (canvas->getItemByID( essentialProp<QString>(node, x_objTwoID))); assert(separation); assert(guide); assert(guide2); activate(no_undo); } }
Guideline *createAlignment(const atypes atype, CanvasItemList items) { Guideline *alignmentGuideline = NULL; QSet<Guideline *> guidelinesToMerge; // Do a first pass to determine alignmentGuideline if there exists a // usuable guideline, as well as record all the guidleines we need to // merge with this one. CanvasItemList::iterator it = items.begin(); while (it != items.end()) { ShapeObj *shape = dynamic_cast<ShapeObj *> (*it); Guideline *guideline = dynamic_cast<Guideline *> (*it); if (shape && (shape->canvasItemFlags() & CanvasItem::ItemIsAlignable)) { // If this is a shape, does it have a relevant guideline. guideline = shape->attachedGuidelineOfType(atype); } if (guideline && (guideline->get_dir() == atypes_to_dirctn(atype))) { if (alignmentGuideline == NULL) { // We use the first guideline as the alignmentGuideline. alignmentGuideline = guideline; } else if (guideline != alignmentGuideline) { // We take note of subsequent guidelines for merging. guidelinesToMerge.insert(guideline); // And we remove this shape or guideline from the items list, // since we will migrate all relationships from the guideline // to the master one for the alignment. it = items.erase(it); continue; } } ++it; } bool firstItem = true; foreach (CanvasItem *item, items) { ShapeObj *shape = dynamic_cast<ShapeObj *> (item); Guideline *guideline = dynamic_cast<Guideline *> (item); if (shape && (shape->canvasItemFlags() & CanvasItem::ItemIsAlignable)) { if (firstItem) { if (alignmentGuideline == NULL) { alignmentGuideline = shape->newGuidelineOfType(atype); } else { // Using a guideline attached to a non-lead shape, we // move the guideline to be positioned relative to the // lead shape. d_printf("\t\tBring guideline to lead shape:\n"); double gx = 0, gy = 0; double value = shape->attachedGuidelinePosition(atype); if (atypes_to_dirctn(atype) == GUIDE_TYPE_VERT) { gx = value; } else { gy = value; } alignmentGuideline->move_to(gx, gy, true, false); } firstItem = false; } Guideline *existingGuideline = shape->attachedGuidelineOfType(atype); if (existingGuideline == NULL) { // This shape isn't attached to a relevant guideline, // so attach it. // UNDO if (recUndo) add_undo_record(DELTA_MOVE, shape); new Relationship(alignmentGuideline, shape, atype); } else { assert(existingGuideline == alignmentGuideline); } } else if (guideline && (guideline->get_dir() == atypes_to_dirctn(atype))) { if (firstItem) { // If this is the lead, do nothing to it. firstItem = false; } assert(guideline == alignmentGuideline); } }
Guideline *createAlignment(const atypes atype, CanvasItemList& objList) { bool first_shape = true; Guideline *guide = NULL; for (CanvasItemList::iterator sh = objList.begin(); sh != objList.end(); sh++) { ShapeObj *shape = dynamic_cast<ShapeObj *> (*sh); Guideline *guidesh = dynamic_cast<Guideline *> (*sh); if (shape && (shape->canvasItemFlags() & CanvasItem::ItemIsAlignable)) { if ((guide = shape->get_guide(atype))) { // found a guide of this type. break; } } else if (guidesh) { // Don't use horizontal guides for vertical alignment. if (guidesh->get_dir() == atypes_to_dirctn(atype)) { guide = guidesh; } break; } } for (CanvasItemList::iterator sh = objList.begin(); sh != objList.end(); ++sh) { ShapeObj *shape = dynamic_cast<ShapeObj *> (*sh); Guideline *guidesh = dynamic_cast<Guideline *> (*sh); if (shape && (shape->canvasItemFlags() & CanvasItem::ItemIsAlignable)) { if (first_shape) { if (!guide) { guide = shape->new_guide(atype); // UNDO add_undo_record(DELTA_ADD, guide); } else { // Using a guide attached to a non-lead object, // need to move it. d_printf("\t\tBring guideline to lead shape:\n"); double gx = 0, gy = 0; double value = shape->attachedGuidelinePosition(atype); if (atypes_to_dirctn(atype) == GUIDE_TYPE_VERT) { gx = value; } else { gy = value; } guide->move_to(gx, gy, true, false); } first_shape = false; } Guideline *guide2 = shape->get_guide(atype); if (guide2 == NULL) { // UNDO if (recUndo) add_undo_record(DELTA_MOVE, shape); new Relationship(guide, shape, atype); } else if (guide2 != guide) { // UNDO if (recUndo) add_undo_record(DELTA_MOVE, guide2); new Relationship(guide, guide2); } else // if (guide2 == guide) { // This is already attached, so do nothing. } } else if (guidesh && (guidesh->get_dir() == atypes_to_dirctn(atype))) { if (first_shape) { // If this is the lead, do nothing to it. first_shape = false; } else if (guidesh != guide) { // UNDO if (recUndo) add_undo_record(DELTA_MOVE, guidesh); new Relationship(guide, guidesh); } } } if (!guide) { qWarning("No alignment created in createAlignment()."); } return guide; }