File: DesignerMimeData.cpp

package info (click to toggle)
bornagain 1.19.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 91,912 kB
  • sloc: cpp: 518,586; python: 42,512; xml: 805; awk: 630; sh: 470; ansic: 37; makefile: 25
file content (109 lines) | stat: -rw-r--r-- 3,859 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/coregui/Views/SampleDesigner/DesignerMimeData.cpp
//! @brief     Implements class DesignerMimeData
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "GUI/coregui/Views/SampleDesigner/DesignerMimeData.h"
#include "GUI/coregui/Views/SampleDesigner/DesignerHelper.h"
#include <QBitmap>
#include <QByteArray>
#include <QDataStream>
#include <QDrag>
#include <QPainter>
#include <QPixmap>
#include <QWidget>
#include <QXmlStreamReader>
#include <iostream>

#if QT_VERSION < 0x050000
#define QStringLiteral QString
#endif

DesignerMimeData::DesignerMimeData(const QString& entryname, const QString& xmldescr, QDrag* drag)
    : m_entryname(entryname), m_xmldescr(xmldescr)
{
    drag->setMimeData(this);

    read_xmldescr(m_xmldescr);

    QByteArray itemData;
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    dataStream << xmldescr;
    setData("bornagain/widget", itemData);

    drag->setPixmap(getPixmap(m_classname));
    drag->setHotSpot(QPoint(drag->pixmap().width() / 2, drag->pixmap().height() / 2));
}

void DesignerMimeData::read_xmldescr(const QString& xmldescr)
{
    QXmlStreamReader reader(xmldescr);

    bool widget_found = false;
    while (!reader.atEnd()) {
        if (reader.readNext() == QXmlStreamReader::StartElement) {
            const QStringRef name = reader.name();
            if (widget_found)
                reader.raiseError("Unexpected element <" + name.toString() + ">");
            if (name.compare(QStringLiteral("widget"), Qt::CaseInsensitive) == 0)
                read_widget(reader);
            else
                reader.raiseError("Unexpected element <" + name.toString() + ">");
        }
    }
    if (reader.hasError()) {
        QString errorMessage = tr("A parse error occurred at line %1, column %2 of the XML code "
                                  "specified for the widget %3: %4\n%5")
                                   .arg(reader.lineNumber())
                                   .arg(reader.columnNumber())
                                   .arg(m_entryname)
                                   .arg(reader.errorString())
                                   .arg(xmldescr);
        std::cout << "DesignerMimeData::read_xmldescr() -> Error during parse." << std::endl;
        std::cout << errorMessage.toStdString() << std::endl;
    }
}

// extract class name and skip the rest
void DesignerMimeData::read_widget(QXmlStreamReader& reader)
{
    for (const QXmlStreamAttribute& attribute : reader.attributes()) {
        QStringRef name = attribute.name();
        if (name == "class") {
            m_classname = attribute.value().toString();
            continue;
        }
        reader.raiseError("Unexpected attribute " + name.toString());
    }
    reader.skipCurrentElement();
}

// Execute a drag and drop operation.
Qt::DropAction DesignerMimeData::execDrag(const QString& name, const QString& xmldescr,
                                          QWidget* dragSource)
{
    if (xmldescr.size() == 0)
        return Qt::IgnoreAction;

    QDrag* drag = new QDrag(dragSource);
    DesignerMimeData* mimeData = new DesignerMimeData(name, xmldescr, drag);
    Q_UNUSED(mimeData);

    const Qt::DropAction executedAction = drag->exec(Qt::CopyAction);

    return executedAction;
}

QPixmap DesignerMimeData::getPixmap(const QString& name)
{
    return DesignerHelper::getMimePixmap(name);
}