~ubuntu-branches/ubuntu/wily/psi/wily

« back to all changes in this revision

Viewing changes to src/whiteboarding/wbscene.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-08-28 18:46:52 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080828184652-iiik12dl91nq7cdi
Tags: 0.12-2
Uploading to unstable (Closes: Bug#494352)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * wbscene.cpp - an SVG whiteboard scene class
 
3
 * Copyright (C) 2006  Joonas Govenius
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License
 
7
 * as published by the Free Software Foundation; either version 2
 
8
 * of the License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 *
 
19
 */
 
20
 
 
21
#include "wbscene.h"
 
22
 
 
23
WbScene::WbScene(SxeSession* session, QObject * parent) : QGraphicsScene(parent) {
 
24
    session_ = session;
 
25
};
 
26
 
 
27
void WbScene::queueTransformationRegeneration(WbItem* item) {
 
28
        if(item && !pendingTranformations_.contains(item))
 
29
                pendingTranformations_.append(QPointer<WbItem>(item));
 
30
}
 
31
 
 
32
void WbScene::regenerateTransformations() {
 
33
        foreach(QPointer<WbItem> item, pendingTranformations_) {
 
34
                if(item) {
 
35
            // qDebug(QString("Regenerating %1 transform.").arg((unsigned int) &(*item)).toAscii());
 
36
                        item->regenerateTransform();
 
37
                }
 
38
        }
 
39
        pendingTranformations_.clear();
 
40
    session_->flush();
 
41
}
 
42
 
 
43
QPointF WbScene::selectionCenter() const {
 
44
    QList<QGraphicsItem*> items = selectedItems();
 
45
 
 
46
    if(items.size() < 1)
 
47
        return QPointF();
 
48
 
 
49
    QRectF box = items.at(0)->sceneBoundingRect();
 
50
    foreach(QGraphicsItem* item, items) {
 
51
        box = box.united(item->sceneBoundingRect());
 
52
    }
 
53
 
 
54
    // qDebug(QString("Selection center: %1 %2").arg(box.center().x()).arg(box.center().y()).toAscii());
 
55
 
 
56
    return box.center();
 
57
}
 
58
 
 
59
void WbScene::bringForward(int n) {
 
60
    bring(n, false);
 
61
}
 
62
 
 
63
void WbScene::bringToFront() {
 
64
    bring(1, true);
 
65
}
 
66
 
 
67
void WbScene::sendBackwards(int n) {
 
68
    bring(-n, false);
 
69
}
 
70
 
 
71
void WbScene::sendToBack() {
 
72
    bring(-1, true);
 
73
}
 
74
 
 
75
static bool zValueLessThan(QGraphicsItem* item1, QGraphicsItem* item2) {
 
76
    return (item1->zValue() < item2->zValue());
 
77
}
 
78
 
 
79
void WbScene::group() {
 
80
    if(selectedItems().size() > 1) {
 
81
        // Create the group
 
82
        QDomElement temp = QDomDocument().createElement("g");
 
83
        temp.setAttribute("id", "e" + SxeSession::generateUUID());
 
84
        const QDomNode group = session_->insertNodeAfter(temp, session_->document().documentElement());
 
85
 
 
86
        // Arrange the items by Z coordinate
 
87
        QList<QGraphicsItem*> selected = selectedItems();
 
88
        qSort(selected.begin(), selected.end(), zValueLessThan);
 
89
 
 
90
        // Reparent each selected item
 
91
        foreach(QGraphicsItem* item, selected) {
 
92
            WbItem* wbitem = dynamic_cast<WbItem*>(item);
 
93
            if(wbitem)
 
94
                session_->insertNodeAfter(wbitem->node(), group);
 
95
        }
 
96
        clearSelection();
 
97
        
 
98
        session_->flush();
 
99
    }
 
100
}
 
101
 
 
102
void WbScene::ungroup() {
 
103
    foreach(QGraphicsItem* item, selectedItems()) {        
 
104
        // find the QDomElement matching the selected item
 
105
        WbItem* wbitem = dynamic_cast<WbItem*>(item);
 
106
        if(wbitem) {
 
107
            QDomElement group = wbitem->node().toElement();
 
108
 
 
109
            if(group.nodeName() == "g") {
 
110
                QDomNodeList children = group.childNodes();
 
111
 
 
112
                QMatrix groupTransform = WbItem::parseSvgTransform(group.attribute("transform"));
 
113
 
 
114
                for(int i = children.size() - 1; i >= 0; i--) {
 
115
                    QDomElement child = children.at(i).toElement();
 
116
                    if(!child.isNull()) {
 
117
 
 
118
                        if(!groupTransform.isIdentity()) {
 
119
                            // combine the transformations of the group and the child
 
120
                            QMatrix childTransform = WbItem::parseSvgTransform(child.attribute("transform"));
 
121
                            session_->setAttribute(child, "transform", WbItem::toSvgTransform(childTransform * groupTransform));
 
122
                        }
 
123
 
 
124
                        // move the child from the group to the root <svg/>
 
125
                        session_->insertNodeAfter(children.at(i), session_->document().documentElement(), group);
 
126
 
 
127
                    }
 
128
                }
 
129
            
 
130
                // delete the group itself
 
131
                session_->removeNode(group);
 
132
            }
 
133
 
 
134
        }
 
135
    }
 
136
    clearSelection();
 
137
 
 
138
    session_->flush();
 
139
}
 
140
 
 
141
void WbScene::bring(int n, bool toExtremum) {
 
142
    if(n == 0)
 
143
         return;
 
144
 
 
145
    // bring each selected item
 
146
    foreach(QGraphicsItem* selecteditem, selectedItems()) {
 
147
 
 
148
        if (!(selecteditem->parentItem() && selecteditem->parentItem()->isSelected())) {
 
149
 
 
150
            WbItem* selectedwbitem = dynamic_cast<WbItem*>(selecteditem);
 
151
 
 
152
            if(selectedwbitem) {
 
153
 
 
154
                QList<QGraphicsItem*> colliding = selecteditem->collidingItems();
 
155
                
 
156
                // find the relative position of selecteditem itself and
 
157
                // remove other selected items from the list colliding
 
158
                int i = 0;
 
159
                while(i < colliding.size()) {
 
160
                    if(selectedItems().contains(colliding[i])) {
 
161
                        colliding.removeAt(i);
 
162
                    } else if(colliding[i]->zValue() < selecteditem->zValue()) {
 
163
                        break;
 
164
                    } else
 
165
                        i++;
 
166
                }
 
167
                if(n < 0)
 
168
                    i--;
 
169
 
 
170
                // bring the selected node n levels above/below the item itself
 
171
                if(colliding.size() > 0) {
 
172
                    WbItem* referencewbitem;
 
173
                    if(n > 0) {
 
174
                        if(i - n > 0 && !toExtremum)
 
175
                            referencewbitem = dynamic_cast<WbItem*>(colliding[i - n]);
 
176
                        else
 
177
                            referencewbitem = dynamic_cast<WbItem*>(colliding[0]);
 
178
                    } else {
 
179
                        if(i - n < colliding.size() && !toExtremum)
 
180
                            referencewbitem = dynamic_cast<WbItem*>(colliding[i - n]);
 
181
                        else
 
182
                            referencewbitem = dynamic_cast<WbItem*>(colliding[colliding.size() - 1]);
 
183
                    }
 
184
 
 
185
                    if(referencewbitem && !referencewbitem->node().isNull()) {
 
186
                        if(n > 0)
 
187
                            session_->insertNodeAfter(selectedwbitem->node(), selectedwbitem->node().parentNode(), referencewbitem->node());
 
188
                        else
 
189
                            session_->insertNodeBefore(selectedwbitem->node(), selectedwbitem->node().parentNode(), referencewbitem->node());
 
190
                    }
 
191
                }
 
192
            }
 
193
        }
 
194
    }
 
195
 
 
196
    session_->flush();
 
197
}