1 /*
2 * C++ wrapper of DiagramData - just to have something clean to wrap
3 *
4 * Copyright (C) 2007, Hans Breuer, <Hans@Breuer.Org>
5 *
6 * This is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20 #include "object.h"
21 #include "diagramdata.h"
22 #include <assert.h>
23
24 #include "dia-object.h"
25
26 #include "dia-diagramdata.h"
27
28 //! how many contained
29 int
len() const30 dia::Objects::len () const
31 {
32 if (list)
33 return g_list_length(*list);
34 return 0;
35 }
36 //! \brief return back a single one
37 //! Together with len() getitem() allows list access. The code generator needs some
38 //! extra help to not making it an endless list. At least for Python the NULL return
39 //! was turned into None objects, we want to have only as much list elements
40 //! as there are real objects.
41 dia::Object*
getitem(int n) const42 dia::Objects::getitem (int n) const
43 {
44 if (list && n >= 0 && n < g_list_length(*list))
45 return new dia::Object((::DiaObject*)g_list_nth_data(*list, n));
46 return 0;
47 }
48
49 //! construct with underlying list of objects
50 //! \todo check ownership/lifetime of that list!
Layer(::Layer * layer)51 dia::Layer::Layer (::Layer* layer) : self(layer), _found(0)
52 {
53 assert (self);
54 // todo: when we allow to change the name this needs to change
55 name = g_strdup (self->name);
56 objects = new dia::Objects(&(layer->objects));
57 }
~Layer()58 dia::Layer::~Layer ()
59 {
60 if (_found)
61 delete _found;
62 if (name)
63 g_free (const_cast<gchar*>(name));
64 if (objects)
65 delete const_cast<dia::Objects*>(objects);
66 }
67 void
add_object(Object * o)68 dia::Layer::add_object (Object* o)
69 {
70 g_return_if_fail (self != NULL);
71 layer_add_object (self, o->Self());
72 }
73 void
update_extents()74 dia::Layer::update_extents ()
75 {
76 g_return_if_fail (self != NULL);
77 layer_update_extents(self);
78 }
79 //! the object next to given point but within maxdist
80 dia::Object*
find_closest_object(::Point * pos,double maxdist) const81 dia::Layer::find_closest_object (::Point* pos, double maxdist) const
82 {
83 g_return_val_if_fail (self != NULL, 0);
84 ::DiaObject* o = layer_find_closest_object (self, pos, maxdist);
85 if (o)
86 return new dia::Object (o);
87 return 0;
88 }
89 //! a list of Object in the given rectangle
90 dia::Objects&
find_objects_in_rectangle(::Rectangle * rect) const91 dia::Layer::find_objects_in_rectangle (::Rectangle* rect) const
92 {
93 static GList* list = layer_find_objects_in_rectangle (self, rect);
94 if (_found)
95 delete _found;
96 const_cast<Layer*>(this)->_found = new dia::Objects (&list);
97 return *_found;
98 }
99 //! objects are kept in an ordered list, this is the index of the given object
100 int
object_index(Object * o) const101 dia::Layer::object_index (Object* o) const
102 {
103 g_return_val_if_fail (self != NULL, -1);
104 return layer_object_index (self, o->Self());
105 }
106
107 int
len() const108 dia::Layers::len () const
109 {
110 if (list)
111 return (*list)->len;
112 return 0;
113 }
114 dia::Layer*
getitem(int n) const115 dia::Layers::getitem (int n) const
116 {
117 if (list && n >= 0 && n < (*list)->len)
118 return new dia::Layer(static_cast< ::Layer* >(g_ptr_array_index (*list, n)));
119 return 0;
120 }
121
122 /*!
123 * DiagramData is the low level Diagram, i.e. everything without an UI
124 */
DiagramData()125 dia::DiagramData::DiagramData () : self(0), active_layer(0), _selected(0)
126 {
127 // the usual GObjetc cast DIA_DIAGRAM_DATA does not work when playing games with namespaces ;)
128 self = static_cast< ::DiagramData* > (g_object_new (DIA_TYPE_DIAGRAM_DATA, NULL));
129 //FIXME: grumpf
130 if (self->active_layer)
131 active_layer = new Layer(self->active_layer);
132 else if (self->layers->len > 0)
133 active_layer = new Layer((::Layer*)g_ptr_array_index(self->layers, 0));
134 layers = new Layers(&self->layers);
135 }
~DiagramData()136 dia::DiagramData::~DiagramData ()
137 {
138 g_object_unref (self);
139 if (_selected)
140 delete _selected;
141 if (layers)
142 delete const_cast< dia::Layers* >(layers);
143 }
144
145 dia::Layer*
add_layer(const char * name)146 dia::DiagramData::add_layer (const char* name)
147 {
148 int pos = -1; //TODO: make this a parameter
149 g_return_val_if_fail (self != NULL, 0);
150 ::Layer* layer = new_layer(g_strdup(name),self);
151 if (pos != -1)
152 data_add_layer_at(self, layer, pos);
153 else
154 data_add_layer(self, layer);
155
156 dia::Layer* dl = new dia::Layer (layer);
157 return dl;
158 }
159 void
update_extents()160 dia::DiagramData::update_extents ()
161 {
162 g_return_if_fail(self != NULL);
163 data_update_extents(self);
164 // conceptionally const, i.e. read-only
165 *const_cast< ::Rectangle* >(&extents) = self->extents;
166 }
167 dia::Objects&
get_sorted_selected() const168 dia::DiagramData::get_sorted_selected () const
169 {
170 if (_selected)
171 delete _selected;
172
173 static GList* list = data_get_sorted_selected(self);
174 const_cast< DiagramData* >(this)->_selected = new dia::Objects (&list);
175 return *_selected;
176 }
177
178