Beispiel #1
0
/*!
 * paste only one object type so handlePaste can control the order of creation
 */
static GraphObjectList handlePasteType(GraphDraw *draw, const Poco::JSON::Array::Ptr &graphObjects, const std::string &type)
{
    GraphObjectList newObjects;
    for (size_t objIndex = 0; objIndex < graphObjects->size(); objIndex++)
    {
        const auto jGraphObj = graphObjects->getObject(objIndex);
        const auto what = jGraphObj->getValue<std::string>("what");
        GraphObject *obj = nullptr;
        if (what != type) continue;
        if (what == "Block") obj = new GraphBlock(draw);
        if (what == "Breaker") obj = new GraphBreaker(draw);
        if (what == "Connection") obj = new GraphConnection(draw);
        if (what == "Widget") obj = new GraphWidget(draw);
        if (obj == nullptr) continue;
        try {obj->deserialize(jGraphObj);}
        catch (const Pothos::NotFoundException &)
        {
            delete obj;
            continue;
        }
        obj->setSelected(true);
        newObjects.push_back(obj);
    }
    return newObjects;
}
Beispiel #2
0
void GraphEditor::handleBlockXcrement(const int adj)
{
    if (not this->isVisible()) return;
    auto draw = this->getCurrentGraphDraw();
    GraphObjectList changedObjects;
    for (auto obj : draw->getObjectsSelected(GRAPH_BLOCK))
    {
        auto block = dynamic_cast<GraphBlock *>(obj);
        assert(block != nullptr);
        for (const auto &propKey : block->getProperties())
        {
            auto paramDesc = block->getParamDesc(propKey);
            if (paramDesc->has("widgetType") and paramDesc->getValue<std::string>("widgetType") == "SpinBox")
            {
                const auto newValue = block->getPropertyValue(propKey).toInt() + adj;
                block->setPropertyValue(propKey, QString("%1").arg(newValue));
                changedObjects.push_back(block);
                break;
            }
        }
    }

    if (changedObjects.empty()) return;
    const auto desc = (changedObjects.size() == 1)? changedObjects.front()->getId() : tr("selected");
    if (adj > 0) handleStateChange(GraphState("list-add", tr("Increment %1").arg(desc)));
    if (adj < 0) handleStateChange(GraphState("list-remove", tr("Decrement %1").arg(desc)));
}
GraphObjectList GraphDraw::getObjectsSelected(const int selectionFlags)
{
    GraphObjectList objectsSelected;
    for (auto obj : this->getGraphObjects(selectionFlags))
    {
        if (obj->isSelected()) objectsSelected.push_back(obj);
    }
    return objectsSelected;
}
GraphObjectList GraphDraw::getObjectsAtPos(const QPoint &pos)
{
    GraphObjectList graphObjs;
    const auto objs = this->items(pos);
    for (auto obj : objs)
    {
        auto graphObj = dynamic_cast<GraphObject *>(obj);
        if (graphObj != nullptr) graphObjs.push_back(graphObj);
    }
    return graphObjs;
}
Beispiel #5
0
GraphObjectList GraphEditor::getGraphObjects(const int selectionFlags) const
{
    GraphObjectList all;
    for (int i = 0; i < this->count(); i++)
    {
        for (auto obj : this->getGraphDraw(i)->getGraphObjects(selectionFlags))
        {
            all.push_back(obj);
        }
    }
    return all;
}
GraphObjectList GraphDraw::getGraphObjects(const int selectionFlags)
{
    GraphObjectList l;
    for (auto child : this->items())
    {
        auto o = dynamic_cast<GraphObject *>(child);
        if (o == nullptr) continue;
        if (((selectionFlags & GRAPH_BLOCK) != 0) and (qobject_cast<GraphBlock *>(o) != nullptr)) l.push_back(o);
        if (((selectionFlags & GRAPH_BREAKER) != 0) and (qobject_cast<GraphBreaker *>(o) != nullptr)) l.push_back(o);
        if (((selectionFlags & GRAPH_CONNECTION) != 0) and (qobject_cast<GraphConnection *>(o) != nullptr)) l.push_back(o);
        if (((selectionFlags & GRAPH_WIDGET) != 0) and (qobject_cast<GraphWidget *>(o) != nullptr)) l.push_back(o);
    }
    return l;
}
Beispiel #7
0
void GraphEditor::handlePaste(void)
{
    if (not this->isVisible()) return;
    auto draw = this->getCurrentGraphDraw();

    auto mimeData = QApplication::clipboard()->mimeData();
    const bool canPaste = mimeData->hasFormat("text/json/pothos_object_array") and
                      not mimeData->data("text/json/pothos_object_array").isEmpty();
    if (not canPaste) return;

    //extract object array
    const auto data = mimeData->data("text/json/pothos_object_array");
    const std::string dataStr(data.constData(), data.size());
    std::istringstream iss(dataStr);
    Poco::JSON::Parser p; p.parse(iss);
    auto graphObjects = p.getHandler()->asVar().extract<Poco::JSON::Array::Ptr>();
    assert(graphObjects);

    //rewrite ids
    std::map<std::string, std::string> oldIdToNew;
    for (size_t objIndex = 0; objIndex < graphObjects->size(); objIndex++)
    {
        const auto jGraphObj = graphObjects->getObject(objIndex);
        auto oldId = jGraphObj->getValue<std::string>("id");
        oldIdToNew[oldId] = this->newId(QString::fromStdString(oldId)).toStdString();
    }
    for (size_t objIndex = 0; objIndex < graphObjects->size();)
    {
        for (auto &pair : *graphObjects->getObject(objIndex))
        {
            if (QString::fromStdString(pair.first).endsWith("id", Qt::CaseInsensitive))
            {
                //if not in oldIdToNew, remove from list
                if (oldIdToNew.count(pair.second) == 0)
                {
                    graphObjects->remove(objIndex);
                    goto nextObj;
                }
                pair.second = oldIdToNew[pair.second];
            }
        }
        objIndex++;
        nextObj: continue;
    }

    //unselect all objects
    draw->deselectAllObjs();

    //create objects
    GraphObjectList objsToMove;
    objsToMove.append(handlePasteType(draw, graphObjects, "Block"));
    objsToMove.append(handlePasteType(draw, graphObjects, "Breaker"));
    handlePasteType(draw, graphObjects, "Connection"); //dont append, connection position doesnt matter
    objsToMove.append(handlePasteType(draw, graphObjects, "Widget"));

    //deal with initial positions of pasted objects
    QPointF cornerest(1e6, 1e6);
    for (auto obj : objsToMove)
    {
        cornerest.setX(std::min(cornerest.x(), obj->pos().x()));
        cornerest.setY(std::min(cornerest.y(), obj->pos().y()));
    }

    //determine an acceptable position to center the paste
    auto view = dynamic_cast<QGraphicsView *>(this->currentWidget());
    auto pastePos = view->mapToScene(view->mapFromGlobal(QCursor::pos()));
    if (not view->sceneRect().contains(pastePos))
    {
        pastePos = view->mapToScene(this->size().width()/2, this->size().height()/2);
    }

    //move objects into position
    for (auto obj : objsToMove) obj->setPos(obj->pos()-cornerest+pastePos);

    handleStateChange(GraphState("edit-paste", tr("Paste %1").arg(draw->getSelectionDescription())));
}