2
* wbscene.cpp - an SVG whiteboard scene class
3
* Copyright (C) 2006 Joonas Govenius
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.
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.
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
23
WbScene::WbScene(SxeSession* session, QObject * parent) : QGraphicsScene(parent) {
27
void WbScene::queueTransformationRegeneration(WbItem* item) {
28
if(item && !pendingTranformations_.contains(item))
29
pendingTranformations_.append(QPointer<WbItem>(item));
32
void WbScene::regenerateTransformations() {
33
foreach(QPointer<WbItem> item, pendingTranformations_) {
35
// qDebug(QString("Regenerating %1 transform.").arg((unsigned int) &(*item)).toAscii());
36
item->regenerateTransform();
39
pendingTranformations_.clear();
43
QPointF WbScene::selectionCenter() const {
44
QList<QGraphicsItem*> items = selectedItems();
49
QRectF box = items.at(0)->sceneBoundingRect();
50
foreach(QGraphicsItem* item, items) {
51
box = box.united(item->sceneBoundingRect());
54
// qDebug(QString("Selection center: %1 %2").arg(box.center().x()).arg(box.center().y()).toAscii());
59
void WbScene::bringForward(int n) {
63
void WbScene::bringToFront() {
67
void WbScene::sendBackwards(int n) {
71
void WbScene::sendToBack() {
75
static bool zValueLessThan(QGraphicsItem* item1, QGraphicsItem* item2) {
76
return (item1->zValue() < item2->zValue());
79
void WbScene::group() {
80
if(selectedItems().size() > 1) {
82
QDomElement temp = QDomDocument().createElement("g");
83
temp.setAttribute("id", "e" + SxeSession::generateUUID());
84
const QDomNode group = session_->insertNodeAfter(temp, session_->document().documentElement());
86
// Arrange the items by Z coordinate
87
QList<QGraphicsItem*> selected = selectedItems();
88
qSort(selected.begin(), selected.end(), zValueLessThan);
90
// Reparent each selected item
91
foreach(QGraphicsItem* item, selected) {
92
WbItem* wbitem = dynamic_cast<WbItem*>(item);
94
session_->insertNodeAfter(wbitem->node(), group);
102
void WbScene::ungroup() {
103
foreach(QGraphicsItem* item, selectedItems()) {
104
// find the QDomElement matching the selected item
105
WbItem* wbitem = dynamic_cast<WbItem*>(item);
107
QDomElement group = wbitem->node().toElement();
109
if(group.nodeName() == "g") {
110
QDomNodeList children = group.childNodes();
112
QMatrix groupTransform = WbItem::parseSvgTransform(group.attribute("transform"));
114
for(int i = children.size() - 1; i >= 0; i--) {
115
QDomElement child = children.at(i).toElement();
116
if(!child.isNull()) {
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));
124
// move the child from the group to the root <svg/>
125
session_->insertNodeAfter(children.at(i), session_->document().documentElement(), group);
130
// delete the group itself
131
session_->removeNode(group);
141
void WbScene::bring(int n, bool toExtremum) {
145
// bring each selected item
146
foreach(QGraphicsItem* selecteditem, selectedItems()) {
148
if (!(selecteditem->parentItem() && selecteditem->parentItem()->isSelected())) {
150
WbItem* selectedwbitem = dynamic_cast<WbItem*>(selecteditem);
154
QList<QGraphicsItem*> colliding = selecteditem->collidingItems();
156
// find the relative position of selecteditem itself and
157
// remove other selected items from the list colliding
159
while(i < colliding.size()) {
160
if(selectedItems().contains(colliding[i])) {
161
colliding.removeAt(i);
162
} else if(colliding[i]->zValue() < selecteditem->zValue()) {
170
// bring the selected node n levels above/below the item itself
171
if(colliding.size() > 0) {
172
WbItem* referencewbitem;
174
if(i - n > 0 && !toExtremum)
175
referencewbitem = dynamic_cast<WbItem*>(colliding[i - n]);
177
referencewbitem = dynamic_cast<WbItem*>(colliding[0]);
179
if(i - n < colliding.size() && !toExtremum)
180
referencewbitem = dynamic_cast<WbItem*>(colliding[i - n]);
182
referencewbitem = dynamic_cast<WbItem*>(colliding[colliding.size() - 1]);
185
if(referencewbitem && !referencewbitem->node().isNull()) {
187
session_->insertNodeAfter(selectedwbitem->node(), selectedwbitem->node().parentNode(), referencewbitem->node());
189
session_->insertNodeBefore(selectedwbitem->node(), selectedwbitem->node().parentNode(), referencewbitem->node());