コード例 #1
0
void VirtualConsole::slotFont()
{
    bool ok = false;
    QFont font;

    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        font = contents()->font();
    else
        font = m_selectedWidgets.last()->font();

    /* This crashes with Qt 4.6.x on OSX. Upgrade to 4.7.x. */
    font = QFontDialog::getFont(&ok, font);
    if (ok == true)
    {
        if (m_selectedWidgets.isEmpty() == true)
        {
            contents()->setFont(font);
        }
        else
        {
            VCWidget* widget;
            foreach(widget, m_selectedWidgets)
                widget->setFont(font);
        }
    }
}
コード例 #2
0
void VirtualConsole::slotBackgroundColor()
{
    QColor color;

    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        color = contents()->backgroundColor();
    else
        color = m_selectedWidgets.last()->backgroundColor();

    color = QColorDialog::getColor(color);
    if (color.isValid() == true)
    {
        if (m_selectedWidgets.isEmpty() == true)
        {
            contents()->setBackgroundColor(color);
        }
        else
        {
            VCWidget* widget;
            foreach(widget, m_selectedWidgets)
                widget->setBackgroundColor(color);
        }
    }
}
コード例 #3
0
void VirtualConsole::slotBackgroundImage()
{
    QString path;

    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        path = contents()->backgroundImage();
    else
        path = m_selectedWidgets.last()->backgroundImage();

    path = QFileDialog::getOpenFileName(this,
                                        tr("Select background image"),
                                        path,
                                        "Images (*.png *.xpm *.jpg *.gif)");
    if (path.isEmpty() == false)
    {
        if (m_selectedWidgets.isEmpty() == true)
        {
            contents()->setBackgroundImage(path);
        }
        else
        {
            VCWidget* widget;
            foreach(widget, m_selectedWidgets)
                widget->setBackgroundImage(path);
        }
    }
}
コード例 #4
0
void VirtualConsole::slotEditDelete()
{
    QString msg(tr("Do you wish to delete the selected widgets?"));
    QString title(tr("Delete widgets"));
    int result = QMessageBox::question(this, title, msg,
                                       QMessageBox::Yes,
                                       QMessageBox::No);
    if (result == QMessageBox::Yes)
    {
        while (m_selectedWidgets.isEmpty() == false)
        {
            /* Consume the selected list until it is empty and
               delete each widget. */
            VCWidget* widget = m_selectedWidgets.takeFirst();
            widget->deleteLater();

            /* Remove the widget from clipboard as well so that
               deleted widgets won't be pasted anymore anywhere */
            m_clipboard.removeAll(widget);
            m_editPasteAction->setEnabled(false);
        }

        updateActions();
    }
}
コード例 #5
0
void VirtualConsole::updateCustomMenu()
{
    /* Get rid of the custom menu, but delete it later because this might
       be called from the very menu that is being deleted. */
    if (m_customMenu != NULL)
    {
        delete m_customMenu;
        m_customMenu = NULL;
    }

    if (m_selectedWidgets.size() > 0)
    {
        /* Change the custom menu to the last selected widget's menu */
        VCWidget* latestWidget = m_selectedWidgets.last();
        m_customMenu = latestWidget->customMenu(m_editMenu);
        if (m_customMenu != NULL)
            m_editMenu->addMenu(m_customMenu);
    }
    else
    {
        /* Change the custom menu to the bottom frame's menu */
        Q_ASSERT(contents() != NULL);
        m_customMenu = contents()->customMenu(m_editMenu);
        if (m_customMenu != NULL)
            m_editMenu->addMenu(m_customMenu);
    }
}
コード例 #6
0
void VirtualConsole::slotStackingLower()
{
    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        return;

    VCWidget* widget;
    foreach(widget, m_selectedWidgets)
        widget->lower();
}
コード例 #7
0
void VirtualConsole::slotFrameNone()
{
    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        return;

    VCWidget* widget;
    foreach(widget, m_selectedWidgets)
        widget->setFrameStyle(KVCFrameStyleNone);
}
コード例 #8
0
void VirtualConsole::slotForegroundNone()
{
    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        return;

    VCWidget* widget;
    foreach(widget, m_selectedWidgets)
        widget->resetForegroundColor();
}
コード例 #9
0
ファイル: webaccess.cpp プロジェクト: ChrisLaurie/qlcplus
void WebAccess::slotFramePageChanged(int pageNum)
{
    if (m_conn == NULL)
        return;

    VCWidget *frame = (VCWidget *)sender();

    QString wsMessage = QString("%1|FRAME|%2").arg(frame->id()).arg(pageNum);
    QByteArray ba = wsMessage.toUtf8();

    mg_websocket_write(m_conn, WEBSOCKET_OPCODE_TEXT, ba.data(), ba.length());
}
コード例 #10
0
void VirtualConsole::slotEditProperties()
{
    VCWidget* widget;

    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        widget = contents();
    else
        widget = m_selectedWidgets.last();

    if (widget != NULL)
        widget->editProperties();
}
コード例 #11
0
void VCWidgetSelection::updateWidgetsTree()
{
    VCFrame* contents = VirtualConsole::instance()->contents();
    m_widgetsList = getChildren((VCWidget *)contents);

    foreach (QObject *object, m_widgetsList)
    {
        VCWidget *widget = (VCWidget *)object;

        QTreeWidgetItem *item = new QTreeWidgetItem(m_tree);
        item->setText(KColumnName, widget->caption());
        item->setIcon(KColumnName, VCWidget::typeToIcon(widget->type()));
        item->setText(KColumnType, VCWidget::typeToString(widget->type()));
    }
コード例 #12
0
QList<VCWidget *> VCWidgetSelection::getChildren(VCWidget *obj)
{
    QList<VCWidget *> list;
    if (obj == NULL)
        return list;
    QListIterator <VCWidget*> it(obj->findChildren<VCWidget*>());
    while (it.hasNext() == true)
    {
        VCWidget* child = it.next();
        qDebug() << Q_FUNC_INFO << "append: " << child->caption();
        if (m_filters.isEmpty() || m_filters.contains(child->type()))
            list.append(child);
    }
    return list;
}
コード例 #13
0
void VirtualConsole::slotResetFont()
{
    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
    {
        contents()->resetFont();
    }
    else
    {
        VCWidget* widget;
        foreach(widget, m_selectedWidgets)
            widget->resetFont();
    }
}
コード例 #14
0
void VirtualConsole::slotEditRename()
{
    if (m_selectedWidgets.isEmpty() == true)
        return;

    bool ok = false;
    QString text(m_selectedWidgets.last()->caption());
    text = QInputDialog::getText(this, tr("Rename widgets"), tr("Caption:"),
                                 QLineEdit::Normal, text, &ok);
    if (ok == true)
    {
        VCWidget* widget;
        foreach(widget, m_selectedWidgets)
            widget->setCaption(text);
    }
}
コード例 #15
0
void VirtualConsole::slotForegroundColor()
{
    Q_ASSERT(contents() != NULL);

    if (m_selectedWidgets.isEmpty() == true)
        return;

    QColor color(m_selectedWidgets.last()->foregroundColor());
    color = QColorDialog::getColor(color);
    if (color.isValid() == true)
    {
        VCWidget* widget;
        foreach(widget, m_selectedWidgets)
            widget->setForegroundColor(color);
    }
}
コード例 #16
0
ファイル: vcframeproperties.cpp プロジェクト: PML369/qlcplus
void VCFrameProperties::accept()
{
    bool hasHeader = m_frame->isHeaderVisible();

    m_frame->setCaption(m_frameName->text());
    m_frame->setAllowChildren(m_allowChildrenCheck->isChecked());
    m_frame->setAllowResize(m_allowResizeCheck->isChecked());

    /* If the frame is coming from a headerless state,
     * all the children widgets must be moved down */
    if (m_showHeaderCheck->isChecked() && hasHeader == false)
    {
        QListIterator <VCWidget*> it(m_frame->findChildren<VCWidget*>());

        // resize the frame too if it contains children
        if (it.hasNext())
            m_frame->resize(QSize(m_frame->width(), m_frame->height() + 40));

        while (it.hasNext() == true)
        {
            VCWidget* child = it.next();

            // move only first level children
            if (child->parentWidget() == m_frame)
                child->move(QPoint(child->x(), child->y() + 40));
        }
    }
    m_frame->setHeaderVisible(m_showHeaderCheck->isChecked());
    m_frame->setEnableButtonVisible(m_showEnableButtonCheck->isChecked());
    m_frame->setMultipageMode(m_enablePaging->isChecked());
    m_frame->setTotalPagesNumber(m_totalPagesSpin->value());
    m_frame->setPagesLoop(m_pagesLoopCheck->isChecked());

    /* Key sequences */
    m_frame->setEnableKeySequence(m_inputEnableWidget->keySequence());
    m_frame->setNextPageKeySequence(m_inputNextPageWidget->keySequence());
    m_frame->setPreviousPageKeySequence(m_inputPrevPageWidget->keySequence());

    /* Input sources */
    m_frame->setInputSource(m_inputEnableWidget->inputSource(), VCFrame::enableInputSourceId);
    m_frame->setInputSource(m_inputNextPageWidget->inputSource(), VCFrame::nextPageInputSourceId);
    m_frame->setInputSource(m_inputPrevPageWidget->inputSource(), VCFrame::previousPageInputSourceId);

    QDialog::accept();
}
コード例 #17
0
VCWidget* VirtualConsole::closestParent() const
{
    /* If nothing is selected, return the bottom-most contents frame */
    if (m_selectedWidgets.isEmpty() == true)
        return contents();

    /* Find the next VCWidget in the hierarchy that accepts children */
    VCWidget* widget = m_selectedWidgets.last();
    while (widget != NULL)
    {
        if (widget->allowChildren() == true)
            return widget;
        else
            widget = qobject_cast<VCWidget*> (widget->parentWidget());
    }

    return NULL;
}
コード例 #18
0
ファイル: vcframe.cpp プロジェクト: alexpaulzor/qlc
bool VCFrame::saveXML(QDomDocument* doc, QDomElement* vc_root)
{
    QDomElement root;
    QDomElement tag;
    QDomText text;
    QString str;

    Q_ASSERT(doc != NULL);
    Q_ASSERT(vc_root != NULL);

    /* VC Frame entry */
    root = doc->createElement(xmlTagName());
    vc_root->appendChild(root);

    /* Caption */
    root.setAttribute(KXMLQLCVCCaption, caption());

    /* Save appearance */
    saveXMLAppearance(doc, &root);

    /* Save widget proportions only for child frames */
    if (isBottomFrame() == false)
        saveXMLWindowState(doc, &root);

    /* Save children */
    QListIterator <VCWidget*> it(findChildren<VCWidget*>());
    while (it.hasNext() == true)
    {
        VCWidget* widget = it.next();

        /* findChildren() is recursive, so the list contains all
           possible child widgets below this frame. Each frame must
           save only its direct children to preserve hierarchy, so
           save only such widgets that have this widget as their
           direct parent. */
        if (widget->parentWidget() == this)
            widget->saveXML(doc, &root);
    }

    return true;
}
コード例 #19
0
ファイル: webaccess.cpp プロジェクト: ChrisLaurie/qlcplus
mg_result WebAccess::websocketDataHandler(mg_connection *conn)
{
    if (conn == NULL)
        return MG_TRUE;

    m_conn = conn; // store this to send VC loaded async event

    if (conn->content_len == 0)
        return MG_TRUE;

    QString qData = QString(conn->content);
    qData.truncate(conn->content_len);
    qDebug() << "[websocketDataHandler]" << qData;

    QStringList cmdList = qData.split("|");
    if (cmdList.isEmpty())
        return MG_TRUE;

    if(cmdList[0] == "QLC+CMD")
    {
        if (cmdList.count() < 2)
            return MG_FALSE;

        if(cmdList[1] == "opMode")
            emit toggleDocMode();

        return MG_TRUE;
    }
    else if (cmdList[0] == "QLC+IO")
    {
        if (cmdList.count() < 3)
            return MG_FALSE;

        int universe = cmdList[2].toInt();

        if (cmdList[1] == "INPUT")
        {
            m_doc->inputOutputMap()->setInputPatch(universe, cmdList[3], cmdList[4].toUInt());
            m_doc->inputOutputMap()->saveDefaults();
        }
        else if (cmdList[1] == "OUTPUT")
        {
            m_doc->inputOutputMap()->setOutputPatch(universe, cmdList[3], cmdList[4].toUInt(), false);
            m_doc->inputOutputMap()->saveDefaults();
        }
        else if (cmdList[1] == "FB")
        {
            m_doc->inputOutputMap()->setOutputPatch(universe, cmdList[3], cmdList[4].toUInt(), true);
            m_doc->inputOutputMap()->saveDefaults();
        }
        else if (cmdList[1] == "PROFILE")
        {
            InputPatch *inPatch = m_doc->inputOutputMap()->inputPatch(universe);
            if (inPatch != NULL)
            {
                m_doc->inputOutputMap()->setInputPatch(universe, inPatch->pluginName(), inPatch->input(), cmdList[3]);
                m_doc->inputOutputMap()->saveDefaults();
            }
        }
        else if (cmdList[1] == "PASSTHROUGH")
        {
            quint32 uniIdx = cmdList[2].toUInt();
            if (cmdList[3] == "true")
                m_doc->inputOutputMap()->setUniversePassthrough(uniIdx, true);
            else
                m_doc->inputOutputMap()->setUniversePassthrough(uniIdx, false);
            m_doc->inputOutputMap()->saveDefaults();
        }
        else if (cmdList[1] == "AUDIOIN")
        {
            QSettings settings;
            if (cmdList[2] == "__qlcplusdefault__")
                settings.remove(SETTINGS_AUDIO_INPUT_DEVICE);
            else
            {
                settings.setValue(SETTINGS_AUDIO_INPUT_DEVICE, cmdList[2]);
                m_doc->destroyAudioCapture();
            }
        }
        else if (cmdList[1] == "AUDIOOUT")
        {
            QSettings settings;
            if (cmdList[2] == "__qlcplusdefault__")
                settings.remove(SETTINGS_AUDIO_OUTPUT_DEVICE);
            else
                settings.setValue(SETTINGS_AUDIO_OUTPUT_DEVICE, cmdList[2]);
        }
        else
            qDebug() << "[webaccess] Command" << cmdList[1] << "not supported !";

        return MG_TRUE;
    }
#if defined(Q_WS_X11) || defined(Q_OS_LINUX)
    else if(cmdList[0] == "QLC+SYS")
    {
        if (cmdList.at(1) == "NETWORK")
        {
            if (m_netConfig->updateNetworkFile(cmdList) == true)
            {
                QString wsMessage = QString("ALERT|" + tr("Network configuration changed. Reboot to apply the changes."));
                mg_websocket_write(m_conn, WEBSOCKET_OPCODE_TEXT, wsMessage.toUtf8().data(), wsMessage.length());
                return MG_TRUE;
            }
            else
                qDebug() << "[webaccess] Error writing network configuration file !";

            return MG_TRUE;
        }
        else if (cmdList.at(1) == "AUTOSTART")
        {
            if (cmdList.count() < 3)
                return MG_FALSE;

            QString asName = QString("%1/%2/%3").arg(getenv("HOME")).arg(USERQLCPLUSDIR).arg(AUTOSTART_PROJECT_NAME);
            if (cmdList.at(2) == "none")
                QFile::remove(asName);
            else
                emit storeAutostartProject(asName);
            QString wsMessage = QString("ALERT|" + tr("Autostart configuration changed"));
            mg_websocket_write(m_conn, WEBSOCKET_OPCODE_TEXT, wsMessage.toUtf8().data(), wsMessage.length());
            return MG_TRUE;
        }
        else if (cmdList.at(1) == "REBOOT")
        {
            QProcess *rebootProcess = new QProcess();
            rebootProcess->start("reboot", QStringList());
        }
        else if (cmdList.at(1) == "HALT")
        {
            QProcess *haltProcess = new QProcess();
            haltProcess->start("halt", QStringList());
        }
    }
#endif
    else if (cmdList[0] == "QLC+API")
    {
        if (cmdList.count() < 2)
            return MG_FALSE;

        QString apiCmd = cmdList[1];
        // compose the basic API reply messages
        QString wsAPIMessage = QString("QLC+API|%1|").arg(apiCmd);

        if (apiCmd == "isProjectLoaded")
        {
            if (m_pendingProjectLoaded)
            {
                wsAPIMessage.append("true");
                m_pendingProjectLoaded = false;
            }
            else
                wsAPIMessage.append("false");
        }
        else if (apiCmd == "getFunctionsNumber")
        {
            wsAPIMessage.append(QString::number(m_doc->functions().count()));
        }
        else if (apiCmd == "getFunctionsList")
        {
            foreach(Function *f, m_doc->functions())
                wsAPIMessage.append(QString("%1|%2|").arg(f->id()).arg(f->name()));
            // remove trailing separator
            wsAPIMessage.truncate(wsAPIMessage.length() - 1);
        }
        else if (apiCmd == "getFunctionType")
        {
            if (cmdList.count() < 3)
                return MG_FALSE;

            quint32 fID = cmdList[2].toUInt();
            Function *f = m_doc->function(fID);
            if (f != NULL)
                wsAPIMessage.append(m_doc->function(fID)->typeString());
            else
                wsAPIMessage.append(Function::typeToString(Function::Undefined));
        }
        else if (apiCmd == "getFunctionStatus")
        {
            if (cmdList.count() < 3)
                return MG_FALSE;

            quint32 fID = cmdList[2].toUInt();
            Function *f = m_doc->function(fID);
            if (f != NULL)
            {
                if (f->isRunning())
                    wsAPIMessage.append("Running");
                else
                    wsAPIMessage.append("Stopped");
            }
            else
                wsAPIMessage.append(Function::typeToString(Function::Undefined));
        }
        else if (apiCmd == "getWidgetsNumber")
        {
            VCFrame *mainFrame = m_vc->contents();
            QList<VCWidget *> chList = mainFrame->findChildren<VCWidget*>();
            wsAPIMessage.append(QString::number(chList.count()));
        }
        else if (apiCmd == "getWidgetsList")
        {
            VCFrame *mainFrame = m_vc->contents();
            foreach(VCWidget *widget, mainFrame->findChildren<VCWidget*>())
                wsAPIMessage.append(QString("%1|%2|").arg(widget->id()).arg(widget->caption()));
            // remove trailing separator
            wsAPIMessage.truncate(wsAPIMessage.length() - 1);
        }
        else if (apiCmd == "getWidgetType")
        {
            if (cmdList.count() < 3)
                return MG_FALSE;

            quint32 wID = cmdList[2].toUInt();
            VCWidget *widget = m_vc->widget(wID);
            if (widget != NULL)
                wsAPIMessage.append(widget->typeToString(widget->type()));
            else
                wsAPIMessage.append(widget->typeToString(VCWidget::UnknownWidget));
        }
        else if (apiCmd == "getWidgetStatus")
        {
            if (cmdList.count() < 3)
                return MG_FALSE;
            quint32 wID = cmdList[2].toUInt();
            VCWidget *widget = m_vc->widget(wID);
            if (widget != NULL)
            {
                switch(widget->type())
                {
                    case VCWidget::ButtonWidget:
                    {
                        VCButton *button = qobject_cast<VCButton*>(widget);
                        if (button->isOn())
                            wsAPIMessage.append("255");
                        else
                            wsAPIMessage.append("0");
                    }
                    break;
                    case VCWidget::SliderWidget:
                    {
                        VCSlider *slider = qobject_cast<VCSlider*>(widget);
                        wsAPIMessage.append(QString::number(slider->sliderValue()));
                    }
                    break;
                    case VCWidget::CueListWidget:
                    {
                        VCCueList *cue = qobject_cast<VCCueList*>(widget);
                        quint32 chaserID = cue->chaserID();
                        Function *f = m_doc->function(chaserID);
                        if (f != NULL && f->isRunning())
                            wsAPIMessage.append(QString("PLAY|%2|").arg(cue->getCurrentIndex()));
                        else
                            wsAPIMessage.append("STOP");
                    }
                    break;
                }
            }
        }
        else if (apiCmd == "getChannelsValues")
        {
            if (cmdList.count() < 4)
                return MG_FALSE;

            quint32 universe = cmdList[2].toUInt() - 1;
            int startAddr = cmdList[3].toInt() - 1;
            int count = 1;
            if (cmdList.count() == 5)
                count = cmdList[4].toInt();

            wsAPIMessage.append(WebAccessSimpleDesk::getChannelsMessage(m_doc, m_sd, universe, startAddr, count));
        }
        else if (apiCmd == "sdResetUniverse")
        {
            m_sd->resetUniverse();
            wsAPIMessage = "QLC+API|getChannelsValues|";
            wsAPIMessage.append(WebAccessSimpleDesk::getChannelsMessage(
                                m_doc, m_sd, m_sd->getCurrentUniverseIndex(),
                                0, m_sd->getSlidersNumber()));
        }
        //qDebug() << "Simple desk channels:" << wsAPIMessage;

        mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT, wsAPIMessage.toUtf8().data(), wsAPIMessage.length());
        return MG_TRUE;
    }
    else if(cmdList[0] == "CH")
    {
        if (cmdList.count() < 3)
            return MG_FALSE;

        uint absAddress = cmdList[1].toInt() - 1;
        int value = cmdList[2].toInt();
        m_sd->setAbsoluteChannelValue(absAddress, uchar(value));

        return MG_TRUE;
    }
    else if(cmdList[0] == "POLL")
        return MG_TRUE;

    if (qData.contains("|") == false)
        return MG_FALSE;

    quint32 widgetID = cmdList[0].toUInt();
    VCWidget *widget = m_vc->widget(widgetID);
    uchar value = 0;
    if (cmdList.count() > 1)
        value = (uchar)cmdList[1].toInt();
    if (widget != NULL)
    {
        switch(widget->type())
        {
            case VCWidget::ButtonWidget:
            {
                VCButton *button = qobject_cast<VCButton*>(widget);
                if ((value == 0 && button->isOn()) ||
                    (value != 0 && button->isOn() == false))
                        button->pressFunction();
            }
            break;
            case VCWidget::SliderWidget:
            {
                VCSlider *slider = qobject_cast<VCSlider*>(widget);
                slider->setSliderValue(value);
            }
            break;
            case VCWidget::AudioTriggersWidget:
            {
                VCAudioTriggers *triggers = qobject_cast<VCAudioTriggers*>(widget);
                triggers->slotEnableButtonToggled(value ? true : false);
            }
            break;
            case VCWidget::CueListWidget:
            {
                if (cmdList.count() < 2)
                    return MG_FALSE;

                VCCueList *cue = qobject_cast<VCCueList*>(widget);
                if (cmdList[1] == "PLAY")
                    cue->slotPlayback();
                else if (cmdList[1] == "PREV")
                    cue->slotPreviousCue();
                else if (cmdList[1] == "NEXT")
                    cue->slotNextCue();
                else if (cmdList[1] == "STEP")
                    cue->playCueAtIndex(cmdList[2].toInt());
            }
            break;
            case VCWidget::FrameWidget:
            case VCWidget::SoloFrameWidget:
            {
                VCFrame *frame = qobject_cast<VCFrame*>(widget);
                frame->blockSignals(true);
                if (cmdList[1] == "NEXT_PG")
                    frame->slotNextPage();
                else if (cmdList[1] == "PREV_PG")
                    frame->slotPreviousPage();
                frame->blockSignals(false);
            }
            break;
            default:
            break;
        }
    }

    return MG_TRUE;
}
コード例 #20
0
void VirtualConsole::slotEditPaste()
{
    if (m_clipboard.size() == 0)
    {
        /* Invalidate the edit action if there's nothing to paste */
        m_editAction = EditNone;
        m_editPasteAction->setEnabled(false);
        return;
    }

    VCWidget* parent;
    VCWidget* widget;
    QRect bounds;

    Q_ASSERT(contents() != NULL);

    /* Select the parent that gets the cut clipboard contents */
    parent = closestParent();

    /* Get the bounding rect for all selected widgets */
    QListIterator <VCWidget*> it(m_clipboard);
    while (it.hasNext() == true)
    {
        widget = it.next();
        Q_ASSERT(widget != NULL);
        bounds = bounds.united(widget->geometry());
    }

    /* Get the upcoming parent's last mouse click point */
    QPoint cp(parent->lastClickPoint());

    if (m_editAction == EditCut)
    {
        it.toFront();
        while (it.hasNext() == true)
        {
            widget = it.next();
            Q_ASSERT(widget != NULL);
            if (widget == parent)
                continue;

            /* Get widget's relative pos to the bounding rect */
            QPoint p(widget->x() - bounds.x() + cp.x(),
                     widget->y() - bounds.y() + cp.y());

            /* Reparent and move to the correct place */
            widget->setParent(parent);
            widget->move(p);
            widget->show();
        }

        /* Clear clipboard after pasting stuff that was CUT */
        m_clipboard.clear();
        m_editPasteAction->setEnabled(false);
    }
    else if (m_editAction == EditCopy)
    {
        it.toFront();
        while (it.hasNext() == true)
        {
            widget = it.next();
            Q_ASSERT(widget != NULL);
            if (widget == parent)
                continue;

            /* Get widget's relative pos to the bounding rect */
            QPoint p(widget->x() - bounds.x() + cp.x(),
                     widget->y() - bounds.y() + cp.y());

            /* Create a copy and move to correct place */
            VCWidget* copy = widget->createCopy(parent);
            Q_ASSERT(copy != NULL);
            copy->move(p);
            copy->show();
        }
    }

    updateActions();
}