| 1 | #include "graph_displayer_canvas.h" | 
|---|
| 2 | #include <cmath> | 
|---|
| 3 |  | 
|---|
| 4 |  | 
|---|
| 5 | bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event) | 
|---|
| 6 | { | 
|---|
| 7 |   Gnome::Canvas::CanvasAA::on_expose_event(event); | 
|---|
| 8 |   //usleep(10000); | 
|---|
| 9 |   //rezoom(); | 
|---|
| 10 |   return true; | 
|---|
| 11 | } | 
|---|
| 12 |  | 
|---|
| 13 | void GraphDisplayerCanvas::changeEditorialTool(int newtool) | 
|---|
| 14 | { | 
|---|
| 15 |   if(actual_tool!=newtool) | 
|---|
| 16 |     { | 
|---|
| 17 |  | 
|---|
| 18 |       actual_handler.disconnect(); | 
|---|
| 19 |  | 
|---|
| 20 |       switch(actual_tool) | 
|---|
| 21 |         { | 
|---|
| 22 |         case CREATE_EDGE: | 
|---|
| 23 |           { | 
|---|
| 24 |             GdkEvent * generated=new GdkEvent(); | 
|---|
| 25 |             generated->type=GDK_BUTTON_RELEASE; | 
|---|
| 26 |             generated->button.button=3; | 
|---|
| 27 |             createEdgeEventHandler(generated);       | 
|---|
| 28 |             break; | 
|---|
| 29 |           } | 
|---|
| 30 |         case EDGE_MAP_EDIT: | 
|---|
| 31 |           //has to do the same thing as in the case of NODE_MAP_EDIT | 
|---|
| 32 |         case NODE_MAP_EDIT: | 
|---|
| 33 |           { | 
|---|
| 34 |             break; | 
|---|
| 35 |           } | 
|---|
| 36 |         default: | 
|---|
| 37 |           break; | 
|---|
| 38 |         } | 
|---|
| 39 |  | 
|---|
| 40 |       active_item=NULL;  | 
|---|
| 41 |       target_item=NULL;  | 
|---|
| 42 |       active_edge=INVALID;       | 
|---|
| 43 |       active_node=INVALID;       | 
|---|
| 44 |  | 
|---|
| 45 |  | 
|---|
| 46 |       actual_tool=newtool; | 
|---|
| 47 |    | 
|---|
| 48 |       switch(newtool) | 
|---|
| 49 |         { | 
|---|
| 50 |         case MOVE: | 
|---|
| 51 |           actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false); | 
|---|
| 52 |           break; | 
|---|
| 53 |  | 
|---|
| 54 |         case CREATE_NODE: | 
|---|
| 55 |           actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false); | 
|---|
| 56 |           break; | 
|---|
| 57 |  | 
|---|
| 58 |         case CREATE_EDGE: | 
|---|
| 59 |           actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false); | 
|---|
| 60 |           break; | 
|---|
| 61 |  | 
|---|
| 62 |         case ERASER: | 
|---|
| 63 |           actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false); | 
|---|
| 64 |           break; | 
|---|
| 65 |  | 
|---|
| 66 |         case EDGE_MAP_EDIT: | 
|---|
| 67 |           grab_focus(); | 
|---|
| 68 |           actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::edgeMapEditEventHandler), false); | 
|---|
| 69 |           break; | 
|---|
| 70 |  | 
|---|
| 71 |         case NODE_MAP_EDIT: | 
|---|
| 72 |           actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::nodeMapEditEventHandler), false); | 
|---|
| 73 |           break; | 
|---|
| 74 |  | 
|---|
| 75 |         default: | 
|---|
| 76 |           break; | 
|---|
| 77 |         } | 
|---|
| 78 |     } | 
|---|
| 79 | } | 
|---|
| 80 |  | 
|---|
| 81 | int GraphDisplayerCanvas::getActualTool() | 
|---|
| 82 | { | 
|---|
| 83 |   return actual_tool; | 
|---|
| 84 | } | 
|---|
| 85 |  | 
|---|
| 86 | bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e) | 
|---|
| 87 | { | 
|---|
| 88 |   static Gnome::Canvas::Text *coord_text = 0; | 
|---|
| 89 |   switch(e->type) | 
|---|
| 90 |   { | 
|---|
| 91 |     case GDK_BUTTON_PRESS: | 
|---|
| 92 |       //we mark the location of the event to be able to calculate parameters of dragging | 
|---|
| 93 |       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 94 |  | 
|---|
| 95 |       active_item=(get_item_at(clicked_x, clicked_y)); | 
|---|
| 96 |       active_node=INVALID; | 
|---|
| 97 |       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 98 |         { | 
|---|
| 99 |           if(nodesmap[i]==active_item) | 
|---|
| 100 |             { | 
|---|
| 101 |               active_node=i; | 
|---|
| 102 |             } | 
|---|
| 103 |         } | 
|---|
| 104 |       switch(e->button.button) | 
|---|
| 105 |         { | 
|---|
| 106 |         case 3:       | 
|---|
| 107 |           isbutton=3; | 
|---|
| 108 |           break; | 
|---|
| 109 |         default: | 
|---|
| 110 |           isbutton=1; | 
|---|
| 111 |           break; | 
|---|
| 112 |         } | 
|---|
| 113 |       break; | 
|---|
| 114 |     case GDK_BUTTON_RELEASE: | 
|---|
| 115 |       if (coord_text) | 
|---|
| 116 |       { | 
|---|
| 117 |         delete coord_text; | 
|---|
| 118 |         coord_text = 0; | 
|---|
| 119 |       } | 
|---|
| 120 |       isbutton=0; | 
|---|
| 121 |       active_item=NULL; | 
|---|
| 122 |       active_node=INVALID; | 
|---|
| 123 |       break; | 
|---|
| 124 |     case GDK_MOTION_NOTIFY: | 
|---|
| 125 |       //we only have to do sg. if the mouse button is pressed AND the click was on a node that was found in the set of nodes | 
|---|
| 126 |       if(active_node!=INVALID) | 
|---|
| 127 |       { | 
|---|
| 128 |         (mytab.mapstorage).modified = true; | 
|---|
| 129 |  | 
|---|
| 130 |         //new coordinates will be the old values, | 
|---|
| 131 |         //because the item will be moved to the | 
|---|
| 132 |         //new coordinate therefore the new movement | 
|---|
| 133 |         //has to be calculated from here | 
|---|
| 134 |  | 
|---|
| 135 |         double new_x, new_y; | 
|---|
| 136 |  | 
|---|
| 137 |         window_to_world (e->motion.x, e->motion.y, new_x, new_y); | 
|---|
| 138 |  | 
|---|
| 139 |         double dx=new_x-clicked_x; | 
|---|
| 140 |         double dy=new_y-clicked_y; | 
|---|
| 141 |  | 
|---|
| 142 |         //repositioning node and its text | 
|---|
| 143 |         active_item->move(dx, dy); | 
|---|
| 144 |         nodetextmap[active_node]->move(dx, dy); | 
|---|
| 145 |  | 
|---|
| 146 |         // the new coordinates of the centre of the node  | 
|---|
| 147 |         double coord_x = new_x - (clicked_x - (mytab.mapstorage).coords[active_node].x); | 
|---|
| 148 |         double coord_y = new_y - (clicked_y - (mytab.mapstorage).coords[active_node].y); | 
|---|
| 149 |  | 
|---|
| 150 |         // write back the new coordinates to the coords map | 
|---|
| 151 |         (mytab.mapstorage).coords.set(active_node, xy<double>(coord_x, coord_y)); | 
|---|
| 152 |  | 
|---|
| 153 |         clicked_x=new_x; | 
|---|
| 154 |         clicked_y=new_y; | 
|---|
| 155 |  | 
|---|
| 156 |         // reposition the coordinates text | 
|---|
| 157 |         std::ostringstream ostr; | 
|---|
| 158 |         ostr << "(" << | 
|---|
| 159 |           (mytab.mapstorage).coords[active_node].x << ", " << | 
|---|
| 160 |           (mytab.mapstorage).coords[active_node].y << ")"; | 
|---|
| 161 |         double radius = | 
|---|
| 162 |           (nodesmap[active_node]->property_x2().get_value() - | 
|---|
| 163 |           nodesmap[active_node]->property_x1().get_value()) / 2.0; | 
|---|
| 164 |         if (coord_text) | 
|---|
| 165 |         { | 
|---|
| 166 |           coord_text->property_text().set_value(ostr.str()); | 
|---|
| 167 |           coord_text->property_x().set_value((mytab.mapstorage).coords[active_node].x + | 
|---|
| 168 |               radius); | 
|---|
| 169 |           coord_text->property_y().set_value((mytab.mapstorage).coords[active_node].y - | 
|---|
| 170 |               radius); | 
|---|
| 171 |         } | 
|---|
| 172 |         else | 
|---|
| 173 |         { | 
|---|
| 174 |           coord_text = new Gnome::Canvas::Text( | 
|---|
| 175 |               displayed_graph, | 
|---|
| 176 |               (mytab.mapstorage).coords[active_node].x + radius, | 
|---|
| 177 |               (mytab.mapstorage).coords[active_node].y - radius, | 
|---|
| 178 |               ostr.str()); | 
|---|
| 179 |           coord_text->property_fill_color().set_value("black"); | 
|---|
| 180 |           coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST); | 
|---|
| 181 |         } | 
|---|
| 182 |  | 
|---|
| 183 |         //all the edges connected to the moved point has to be redrawn | 
|---|
| 184 |         for(OutEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei) | 
|---|
| 185 |         { | 
|---|
| 186 |             XY moved_node_1(coord_x - dx, coord_y - dy); | 
|---|
| 187 |             XY moved_node_2(coord_x, coord_y); | 
|---|
| 188 |             Node target = mytab.mapstorage.graph.target(ei); | 
|---|
| 189 |             XY fix_node(mytab.mapstorage.coords[target].x, | 
|---|
| 190 |                         mytab.mapstorage.coords[target].y); | 
|---|
| 191 |             XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]); | 
|---|
| 192 |  | 
|---|
| 193 |             XY arrow_pos; | 
|---|
| 194 |             if(isbutton==3) | 
|---|
| 195 |               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, false); | 
|---|
| 196 |             else | 
|---|
| 197 |               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, true); | 
|---|
| 198 |  | 
|---|
| 199 |             mytab.mapstorage.arrow_pos.set(ei, arrow_pos); | 
|---|
| 200 |             edgesmap[ei]->draw(); | 
|---|
| 201 |  | 
|---|
| 202 |             //reposition of edgetext | 
|---|
| 203 |             XY text_pos=mytab.mapstorage.arrow_pos[ei]; | 
|---|
| 204 |             text_pos+=(XY(10,10)); | 
|---|
| 205 |             edgetextmap[ei]->property_x().set_value(text_pos.x); | 
|---|
| 206 |             edgetextmap[ei]->property_y().set_value(text_pos.y); | 
|---|
| 207 |         } | 
|---|
| 208 |  | 
|---|
| 209 |         for(InEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei) | 
|---|
| 210 |         { | 
|---|
| 211 |             XY moved_node_1(coord_x - dx, coord_y - dy); | 
|---|
| 212 |             XY moved_node_2(coord_x, coord_y); | 
|---|
| 213 |             Node source = mytab.mapstorage.graph.source(ei); | 
|---|
| 214 |             XY fix_node(mytab.mapstorage.coords[source].x, | 
|---|
| 215 |                         mytab.mapstorage.coords[source].y); | 
|---|
| 216 |             XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]); | 
|---|
| 217 |  | 
|---|
| 218 |             XY arrow_pos; | 
|---|
| 219 |             if(isbutton==3) | 
|---|
| 220 |               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, false); | 
|---|
| 221 |             else | 
|---|
| 222 |               arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, true); | 
|---|
| 223 |  | 
|---|
| 224 |             mytab.mapstorage.arrow_pos.set(ei, arrow_pos); | 
|---|
| 225 |             edgesmap[ei]->draw(); | 
|---|
| 226 |  | 
|---|
| 227 |             //reposition of edgetext | 
|---|
| 228 |             XY text_pos=mytab.mapstorage.arrow_pos[ei]; | 
|---|
| 229 |             text_pos+=(XY(10,10)); | 
|---|
| 230 |             edgetextmap[ei]->property_x().set_value(text_pos.x); | 
|---|
| 231 |             edgetextmap[ei]->property_y().set_value(text_pos.y); | 
|---|
| 232 |         } | 
|---|
| 233 |       } | 
|---|
| 234 |     default: break; | 
|---|
| 235 |   } | 
|---|
| 236 |  | 
|---|
| 237 |   return false; | 
|---|
| 238 | } | 
|---|
| 239 |  | 
|---|
| 240 | XY GraphDisplayerCanvas::calcArrowPos(XY moved_node_1, XY moved_node_2, XY fix_node, XY old_arrow_pos, bool move) | 
|---|
| 241 | { | 
|---|
| 242 |   if(!move) | 
|---|
| 243 |   { | 
|---|
| 244 |     return XY((moved_node_2.x + fix_node.x) / 2.0, (moved_node_2.y + fix_node.y) / 2.0); | 
|---|
| 245 |   } | 
|---|
| 246 |   else | 
|---|
| 247 |   { | 
|---|
| 248 |     ////////////////////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| 249 |     /////////// keeps shape-with scalar multiplication - version 2. | 
|---|
| 250 |     ////////////////////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| 251 |  | 
|---|
| 252 |     //old vector from one to the other node - a | 
|---|
| 253 |     xy<double> a_v(moved_node_1.x-fix_node.x,moved_node_1.y-fix_node.y); | 
|---|
| 254 |     //new vector from one to the other node - b | 
|---|
| 255 |     xy<double> b_v(moved_node_2.x-fix_node.x,moved_node_2.y-fix_node.y); | 
|---|
| 256 |  | 
|---|
| 257 |     double absa=sqrt(a_v.normSquare()); | 
|---|
| 258 |     double absb=sqrt(b_v.normSquare()); | 
|---|
| 259 |  | 
|---|
| 260 |     if ((absa == 0.0) || (absb == 0.0)) | 
|---|
| 261 |     { | 
|---|
| 262 |       return old_arrow_pos; | 
|---|
| 263 |     } | 
|---|
| 264 |     else | 
|---|
| 265 |     { | 
|---|
| 266 |       //old vector from one node to the breakpoint - c | 
|---|
| 267 |       xy<double> c_v(old_arrow_pos.x-fix_node.x,old_arrow_pos.y-fix_node.y); | 
|---|
| 268 |  | 
|---|
| 269 |       //unit vector with the same direction to a_v | 
|---|
| 270 |       xy<double> a_v_u(a_v.x/absa,a_v.y/absa); | 
|---|
| 271 |  | 
|---|
| 272 |       //normal vector of unit vector with the same direction to a_v | 
|---|
| 273 |       xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x); | 
|---|
| 274 |  | 
|---|
| 275 |       //unit vector with the same direction to b_v | 
|---|
| 276 |       xy<double> b_v_u(b_v.x/absb,b_v.y/absb); | 
|---|
| 277 |  | 
|---|
| 278 |       //normal vector of unit vector with the same direction to b_v | 
|---|
| 279 |       xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x); | 
|---|
| 280 |  | 
|---|
| 281 |       //vector c in a_v_u and a_v_u_n co-ordinate system | 
|---|
| 282 |       xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n); | 
|---|
| 283 |  | 
|---|
| 284 |       //new vector from one node to the breakpoint - d - we have to calculate this one | 
|---|
| 285 |       xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n); | 
|---|
| 286 |  | 
|---|
| 287 |       return XY(d_v.x+fix_node.x,d_v.y+fix_node.y); | 
|---|
| 288 |     } | 
|---|
| 289 |   } | 
|---|
| 290 | } | 
|---|
| 291 |  | 
|---|
| 292 | bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e) | 
|---|
| 293 | { | 
|---|
| 294 |   switch(e->type) | 
|---|
| 295 |   { | 
|---|
| 296 |     //move the new node | 
|---|
| 297 |     case GDK_MOTION_NOTIFY: | 
|---|
| 298 |       { | 
|---|
| 299 |         GdkEvent * generated=new GdkEvent(); | 
|---|
| 300 |         generated->motion.x=e->motion.x; | 
|---|
| 301 |         generated->motion.y=e->motion.y; | 
|---|
| 302 |         generated->type=GDK_MOTION_NOTIFY; | 
|---|
| 303 |         moveEventHandler(generated);       | 
|---|
| 304 |         break; | 
|---|
| 305 |       } | 
|---|
| 306 |  | 
|---|
| 307 |     case GDK_BUTTON_RELEASE: | 
|---|
| 308 |       (mytab.mapstorage).modified = true; | 
|---|
| 309 |  | 
|---|
| 310 |       isbutton=1; | 
|---|
| 311 |  | 
|---|
| 312 |       active_node=(mytab.mapstorage).graph.addNode(); | 
|---|
| 313 |  | 
|---|
| 314 |       //initiating values corresponding to new node in maps | 
|---|
| 315 |  | 
|---|
| 316 |       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 317 |  | 
|---|
| 318 |       // update coordinates | 
|---|
| 319 |       (mytab.mapstorage).coords.set(active_node, xy<double>(clicked_x, clicked_y)); | 
|---|
| 320 |  | 
|---|
| 321 |       // update all other maps | 
|---|
| 322 |       for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it = | 
|---|
| 323 |           (mytab.mapstorage).nodemap_storage.begin(); it != | 
|---|
| 324 |           (mytab.mapstorage).nodemap_storage.end(); ++it) | 
|---|
| 325 |       { | 
|---|
| 326 |         if ((it->first != "coordinates_x") && | 
|---|
| 327 |             (it->first != "coordinates_y")) | 
|---|
| 328 |         { | 
|---|
| 329 |           (*(it->second))[active_node] = | 
|---|
| 330 |             (mytab.mapstorage).nodemap_default[it->first]; | 
|---|
| 331 |         } | 
|---|
| 332 |       } | 
|---|
| 333 |       // increment the id map's default value | 
|---|
| 334 |       (mytab.mapstorage).nodemap_default["label"] += 1.0; | 
|---|
| 335 |  | 
|---|
| 336 |       nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph, | 
|---|
| 337 |           clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20); | 
|---|
| 338 |       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]); | 
|---|
| 339 |       *(nodesmap[active_node]) << | 
|---|
| 340 |         Gnome::Canvas::Properties::fill_color("blue"); | 
|---|
| 341 |       *(nodesmap[active_node]) << | 
|---|
| 342 |         Gnome::Canvas::Properties::outline_color("black"); | 
|---|
| 343 |       active_item->raise_to_top(); | 
|---|
| 344 |  | 
|---|
| 345 |       (nodesmap[active_node])->show(); | 
|---|
| 346 |  | 
|---|
| 347 |       nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph, | 
|---|
| 348 |           clicked_x+node_property_defaults[N_RADIUS]+5, | 
|---|
| 349 |           clicked_y+node_property_defaults[N_RADIUS]+5, ""); | 
|---|
| 350 |       nodetextmap[active_node]->property_fill_color().set_value("darkblue"); | 
|---|
| 351 |       nodetextmap[active_node]->raise_to_top(); | 
|---|
| 352 |  | 
|---|
| 353 | //       mapwin.updateNode(active_node); | 
|---|
| 354 |       propertyUpdate(active_node); | 
|---|
| 355 |  | 
|---|
| 356 |       isbutton=0; | 
|---|
| 357 |       target_item=NULL; | 
|---|
| 358 |       active_item=NULL; | 
|---|
| 359 |       active_node=INVALID; | 
|---|
| 360 |       break; | 
|---|
| 361 |     default: | 
|---|
| 362 |       break; | 
|---|
| 363 |   } | 
|---|
| 364 |   return false; | 
|---|
| 365 | } | 
|---|
| 366 |  | 
|---|
| 367 | bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e) | 
|---|
| 368 | { | 
|---|
| 369 |   switch(e->type) | 
|---|
| 370 |   { | 
|---|
| 371 |     case GDK_BUTTON_PRESS: | 
|---|
| 372 |       //in edge creation right button has special meaning | 
|---|
| 373 |       if(e->button.button!=3) | 
|---|
| 374 |       { | 
|---|
| 375 |         //there is not yet selected node | 
|---|
| 376 |         if(active_node==INVALID) | 
|---|
| 377 |         { | 
|---|
| 378 |           //we mark the location of the event to be able to calculate parameters of dragging | 
|---|
| 379 |  | 
|---|
| 380 |           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 381 |  | 
|---|
| 382 |           active_item=(get_item_at(clicked_x, clicked_y)); | 
|---|
| 383 |           active_node=INVALID; | 
|---|
| 384 |           for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 385 |           { | 
|---|
| 386 |             if(nodesmap[i]==active_item) | 
|---|
| 387 |             { | 
|---|
| 388 |               active_node=i; | 
|---|
| 389 |             } | 
|---|
| 390 |           } | 
|---|
| 391 |           //the clicked item is really a node | 
|---|
| 392 |           if(active_node!=INVALID) | 
|---|
| 393 |           { | 
|---|
| 394 |             *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); | 
|---|
| 395 |             isbutton=1; | 
|---|
| 396 |           } | 
|---|
| 397 |           //clicked item was not a node. It could be e.g. edge. | 
|---|
| 398 |           else | 
|---|
| 399 |           { | 
|---|
| 400 |             active_item=NULL; | 
|---|
| 401 |           } | 
|---|
| 402 |         } | 
|---|
| 403 |         //we only have to do sg. if the mouse button | 
|---|
| 404 |         // is pressed already once AND the click was | 
|---|
| 405 |         // on a node that was found in the set of  | 
|---|
| 406 |         //nodes, and now we only search for the second  | 
|---|
| 407 |         //node | 
|---|
| 408 |         else | 
|---|
| 409 |         { | 
|---|
| 410 |           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 411 |           target_item=(get_item_at(clicked_x, clicked_y)); | 
|---|
| 412 |           Node target_node=INVALID; | 
|---|
| 413 |           for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 414 |           { | 
|---|
| 415 |             if(nodesmap[i]==target_item) | 
|---|
| 416 |             { | 
|---|
| 417 |               target_node=i; | 
|---|
| 418 |             } | 
|---|
| 419 |           } | 
|---|
| 420 |           //the clicked item is a node, the edge can be drawn | 
|---|
| 421 |           if(target_node!=INVALID) | 
|---|
| 422 |           { | 
|---|
| 423 |             if(target_node!=active_node)                 | 
|---|
| 424 |             { | 
|---|
| 425 |               (mytab.mapstorage).modified = true; | 
|---|
| 426 |  | 
|---|
| 427 |               *(nodesmap[target_node]) << | 
|---|
| 428 |                 Gnome::Canvas::Properties::fill_color("red"); | 
|---|
| 429 |  | 
|---|
| 430 |               //creating new edge | 
|---|
| 431 |               active_edge=(mytab.mapstorage).graph.addEdge(active_node, | 
|---|
| 432 |                   target_node); | 
|---|
| 433 |  | 
|---|
| 434 |               // update maps | 
|---|
| 435 |               for (std::map<std::string, | 
|---|
| 436 |                   Graph::EdgeMap<double>*>::const_iterator it = | 
|---|
| 437 |                   (mytab.mapstorage).edgemap_storage.begin(); it != | 
|---|
| 438 |                   (mytab.mapstorage).edgemap_storage.end(); ++it) | 
|---|
| 439 |               { | 
|---|
| 440 |                 (*(it->second))[active_edge] = | 
|---|
| 441 |                   (mytab.mapstorage).edgemap_default[it->first]; | 
|---|
| 442 |               } | 
|---|
| 443 |               // increment the id map's default value | 
|---|
| 444 |               (mytab.mapstorage).edgemap_default["label"] += 1.0; | 
|---|
| 445 |  | 
|---|
| 446 |               //calculating coordinates of new edge | 
|---|
| 447 |               Gnome::Canvas::Points coos; | 
|---|
| 448 |               double x1, x2, y1, y2; | 
|---|
| 449 |  | 
|---|
| 450 |               active_item->get_bounds(x1, y1, x2, y2); | 
|---|
| 451 |               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); | 
|---|
| 452 |  | 
|---|
| 453 |               target_item->get_bounds(x1, y1, x2, y2); | 
|---|
| 454 |               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); | 
|---|
| 455 |  | 
|---|
| 456 |               // set the coordinates of the arrow on the new edge | 
|---|
| 457 |               MapStorage& ms = mytab.mapstorage; | 
|---|
| 458 |               ms.arrow_pos.set(active_edge, | 
|---|
| 459 |                   (ms.coords[ms.graph.source(active_edge)] + | 
|---|
| 460 |                    ms.coords[ms.graph.target(active_edge)])/ 2.0); | 
|---|
| 461 |  | 
|---|
| 462 |               //drawing new edge | 
|---|
| 463 |               edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge, | 
|---|
| 464 |                   *this); | 
|---|
| 465 |               *(edgesmap[active_edge]) << | 
|---|
| 466 |                 Gnome::Canvas::Properties::fill_color("green"); | 
|---|
| 467 |               edgesmap[active_edge]->property_width_pixels().set_value(10); | 
|---|
| 468 |  | 
|---|
| 469 |               edgesmap[active_edge]->lower_to_bottom(); | 
|---|
| 470 |  | 
|---|
| 471 |               //initializing edge-text as well, to empty string | 
|---|
| 472 |               XY text_pos=mytab.mapstorage.arrow_pos[active_edge]; | 
|---|
| 473 |               text_pos+=(XY(10,10)); | 
|---|
| 474 |  | 
|---|
| 475 |               edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph, | 
|---|
| 476 |                   text_pos.x, text_pos.y, ""); | 
|---|
| 477 |               edgetextmap[active_edge]->property_fill_color().set_value( | 
|---|
| 478 |                   "darkgreen"); | 
|---|
| 479 |               edgetextmap[active_edge]->raise_to_top(); | 
|---|
| 480 |  | 
|---|
| 481 |               //updating its properties | 
|---|
| 482 | //               mapwin.updateEdge(active_edge); | 
|---|
| 483 |               propertyUpdate(active_edge); | 
|---|
| 484 |             } | 
|---|
| 485 |             else | 
|---|
| 486 |             { | 
|---|
| 487 |               target_node=INVALID; | 
|---|
| 488 |               std::cerr << "Loop edge is not yet implemented!" << std::endl; | 
|---|
| 489 |             } | 
|---|
| 490 |           } | 
|---|
| 491 |           //clicked item was not a node. it could be an e.g. edge. we do not | 
|---|
| 492 |           //deal with it furthermore. | 
|---|
| 493 |           else | 
|---|
| 494 |           { | 
|---|
| 495 |             target_item=NULL; | 
|---|
| 496 |           } | 
|---|
| 497 |         } | 
|---|
| 498 |       } | 
|---|
| 499 |       break; | 
|---|
| 500 |     case GDK_BUTTON_RELEASE: | 
|---|
| 501 |       isbutton=0; | 
|---|
| 502 |       //we clear settings in two cases | 
|---|
| 503 |       //1: the edge is ready (target_item has valid value) | 
|---|
| 504 |       //2: the edge creation is cancelled with right button | 
|---|
| 505 |       if((target_item)||(e->button.button==3)) | 
|---|
| 506 |       { | 
|---|
| 507 |         if(active_item) | 
|---|
| 508 |         { | 
|---|
| 509 |           *active_item << Gnome::Canvas::Properties::fill_color("blue"); | 
|---|
| 510 |           active_item=NULL; | 
|---|
| 511 |         } | 
|---|
| 512 |         if(target_item) | 
|---|
| 513 |         { | 
|---|
| 514 |           *target_item << Gnome::Canvas::Properties::fill_color("blue"); | 
|---|
| 515 |           target_item=NULL; | 
|---|
| 516 |         } | 
|---|
| 517 |         active_node=INVALID; | 
|---|
| 518 |         active_edge=INVALID; | 
|---|
| 519 |       } | 
|---|
| 520 |       break; | 
|---|
| 521 |     default: | 
|---|
| 522 |       break; | 
|---|
| 523 |   } | 
|---|
| 524 |   return false; | 
|---|
| 525 | } | 
|---|
| 526 |  | 
|---|
| 527 | bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e) | 
|---|
| 528 | { | 
|---|
| 529 |   switch(e->type) | 
|---|
| 530 |     { | 
|---|
| 531 |     case GDK_BUTTON_PRESS: | 
|---|
| 532 |       //finding the clicked items | 
|---|
| 533 |       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 534 |       active_item=(get_item_at(clicked_x, clicked_y)); | 
|---|
| 535 |       active_node=INVALID; | 
|---|
| 536 |       active_edge=INVALID; | 
|---|
| 537 |       //was it a node? | 
|---|
| 538 |       for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 539 |         { | 
|---|
| 540 |           if(nodesmap[i]==active_item) | 
|---|
| 541 |             { | 
|---|
| 542 |               active_node=i; | 
|---|
| 543 |             } | 
|---|
| 544 |         } | 
|---|
| 545 |       //or was it an edge? | 
|---|
| 546 |       if(active_node==INVALID) | 
|---|
| 547 |         { | 
|---|
| 548 |           for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 549 |             { | 
|---|
| 550 |               if(edgesmap[i]==active_item) | 
|---|
| 551 |                 { | 
|---|
| 552 |                   active_edge=i; | 
|---|
| 553 |                 } | 
|---|
| 554 |             } | 
|---|
| 555 |         } | 
|---|
| 556 |  | 
|---|
| 557 |       // return if the clicked object is neither an edge nor a node | 
|---|
| 558 |       if (active_edge == INVALID) return false; | 
|---|
| 559 |        | 
|---|
| 560 |       //recolor activated item | 
|---|
| 561 |       if(active_item) | 
|---|
| 562 |         { | 
|---|
| 563 |           *active_item << Gnome::Canvas::Properties::fill_color("red"); | 
|---|
| 564 |         } | 
|---|
| 565 |       break; | 
|---|
| 566 |  | 
|---|
| 567 |     case GDK_BUTTON_RELEASE: | 
|---|
| 568 |       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 569 |       if(active_item) | 
|---|
| 570 |         { | 
|---|
| 571 |           //the cursor was not moved since pressing it | 
|---|
| 572 |           if( active_item == ( get_item_at (clicked_x, clicked_y) ) ) | 
|---|
| 573 |             { | 
|---|
| 574 |               //a node was found | 
|---|
| 575 |               if(active_node!=INVALID) | 
|---|
| 576 |                 { | 
|---|
| 577 |                   (mytab.mapstorage).modified = true; | 
|---|
| 578 |  | 
|---|
| 579 |                   std::set<Graph::Edge> edges_to_delete; | 
|---|
| 580 |  | 
|---|
| 581 |                   for(OutEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e) | 
|---|
| 582 |                     { | 
|---|
| 583 |                       edges_to_delete.insert(e); | 
|---|
| 584 |                     } | 
|---|
| 585 |                    | 
|---|
| 586 |                   for(InEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e) | 
|---|
| 587 |                     { | 
|---|
| 588 |                       edges_to_delete.insert(e); | 
|---|
| 589 |                     } | 
|---|
| 590 |                    | 
|---|
| 591 |                   //deleting collected edges | 
|---|
| 592 |                   for(std::set<Graph::Edge>::iterator | 
|---|
| 593 |                         edge_set_it=edges_to_delete.begin(); | 
|---|
| 594 |                       edge_set_it!=edges_to_delete.end(); | 
|---|
| 595 |                       ++edge_set_it) | 
|---|
| 596 |                     { | 
|---|
| 597 |                       deleteItem(*edge_set_it); | 
|---|
| 598 |                     } | 
|---|
| 599 |                   deleteItem(active_node); | 
|---|
| 600 |                 } | 
|---|
| 601 |               //a simple edge was chosen | 
|---|
| 602 |               else if (active_edge != INVALID) | 
|---|
| 603 |                 { | 
|---|
| 604 |                   deleteItem(active_edge); | 
|---|
| 605 |                 } | 
|---|
| 606 |             } | 
|---|
| 607 |           //pointer was moved, deletion is cancelled | 
|---|
| 608 |           else | 
|---|
| 609 |             { | 
|---|
| 610 |               if(active_node!=INVALID) | 
|---|
| 611 |                 { | 
|---|
| 612 |                   *active_item << Gnome::Canvas::Properties::fill_color("blue"); | 
|---|
| 613 |                 } | 
|---|
| 614 |               else if (active_edge != INVALID) | 
|---|
| 615 |                 { | 
|---|
| 616 |                   *active_item << Gnome::Canvas::Properties::fill_color("green"); | 
|---|
| 617 |                 } | 
|---|
| 618 |             } | 
|---|
| 619 |         } | 
|---|
| 620 |       //reseting datas | 
|---|
| 621 |       active_item=NULL; | 
|---|
| 622 |       active_edge=INVALID; | 
|---|
| 623 |       active_node=INVALID; | 
|---|
| 624 |       break; | 
|---|
| 625 |  | 
|---|
| 626 |     case GDK_MOTION_NOTIFY: | 
|---|
| 627 |       break; | 
|---|
| 628 |  | 
|---|
| 629 |     default: | 
|---|
| 630 |       break; | 
|---|
| 631 |     } | 
|---|
| 632 |   return false; | 
|---|
| 633 | } | 
|---|
| 634 |  | 
|---|
| 635 | bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e) | 
|---|
| 636 | { | 
|---|
| 637 |   if(actual_tool==EDGE_MAP_EDIT) | 
|---|
| 638 |   { | 
|---|
| 639 |     switch(e->type) | 
|---|
| 640 |     { | 
|---|
| 641 |       case GDK_BUTTON_PRESS: | 
|---|
| 642 |         { | 
|---|
| 643 |           //for determine, whether it was an edge | 
|---|
| 644 |           Edge clicked_edge=INVALID; | 
|---|
| 645 |  | 
|---|
| 646 |           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 647 |           active_item=(get_item_at(clicked_x, clicked_y)); | 
|---|
| 648 |  | 
|---|
| 649 |           //find the activated item between texts | 
|---|
| 650 |           for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 651 |           { | 
|---|
| 652 |             //at the same time only one can be active | 
|---|
| 653 |             if(edgetextmap[i]==active_item) | 
|---|
| 654 |             { | 
|---|
| 655 |               clicked_edge=i; | 
|---|
| 656 |             } | 
|---|
| 657 |           } | 
|---|
| 658 |  | 
|---|
| 659 |           //if it was not between texts, search for it between edges | 
|---|
| 660 |           if(clicked_edge==INVALID) | 
|---|
| 661 |           { | 
|---|
| 662 |             for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 663 |             { | 
|---|
| 664 |               //at the same time only one can be active | 
|---|
| 665 |               if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item)) | 
|---|
| 666 |               { | 
|---|
| 667 |                 clicked_edge=i; | 
|---|
| 668 |               } | 
|---|
| 669 |             } | 
|---|
| 670 |           } | 
|---|
| 671 |   | 
|---|
| 672 |           //if it was really an edge... | 
|---|
| 673 |           if(clicked_edge!=INVALID) | 
|---|
| 674 |           { | 
|---|
| 675 |             // the id map is not editable | 
|---|
| 676 |             if (edgemap_to_edit == "label") return 0; | 
|---|
| 677 |  | 
|---|
| 678 |             //and there is activated map | 
|---|
| 679 |             if(edgetextmap[clicked_edge]->property_text().get_value()!="") | 
|---|
| 680 |             { | 
|---|
| 681 |               //activate the general variable for it | 
|---|
| 682 |               active_edge=clicked_edge; | 
|---|
| 683 |  | 
|---|
| 684 |               //create a dialog | 
|---|
| 685 |               Gtk::Dialog dialog("Edit value", true); | 
|---|
| 686 |               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); | 
|---|
| 687 |               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT); | 
|---|
| 688 |               Gtk::VBox* vbox = dialog.get_vbox(); | 
|---|
| 689 |               Gtk::SpinButton spin(0.0, 4); | 
|---|
| 690 |               spin.set_increments(1.0, 10.0); | 
|---|
| 691 |               spin.set_range(-1000000.0, 1000000.0); | 
|---|
| 692 |               spin.set_numeric(true); | 
|---|
| 693 |               vbox->add(spin); | 
|---|
| 694 |               spin.show(); | 
|---|
| 695 |               switch (dialog.run()) | 
|---|
| 696 |               { | 
|---|
| 697 |                 case Gtk::RESPONSE_NONE: | 
|---|
| 698 |                 case Gtk::RESPONSE_CANCEL: | 
|---|
| 699 |                   break; | 
|---|
| 700 |                 case Gtk::RESPONSE_ACCEPT: | 
|---|
| 701 |                   double new_value = spin.get_value(); | 
|---|
| 702 |                   (*(mytab.mapstorage).edgemap_storage[edgemap_to_edit])[active_edge] = | 
|---|
| 703 |                     new_value; | 
|---|
| 704 |                   std::ostringstream ostr; | 
|---|
| 705 |                   ostr << new_value; | 
|---|
| 706 |                   edgetextmap[active_edge]->property_text().set_value( | 
|---|
| 707 |                       ostr.str()); | 
|---|
| 708 |                   //mapwin.updateEdge(active_edge); | 
|---|
| 709 | //                   mapwin.updateEdge(Edge(INVALID)); | 
|---|
| 710 |                   propertyUpdate(Edge(INVALID)); | 
|---|
| 711 |               } | 
|---|
| 712 |             } | 
|---|
| 713 |           } | 
|---|
| 714 |           break; | 
|---|
| 715 |         } | 
|---|
| 716 |       default: | 
|---|
| 717 |         break; | 
|---|
| 718 |     } | 
|---|
| 719 |   } | 
|---|
| 720 |   return false;   | 
|---|
| 721 | } | 
|---|
| 722 |  | 
|---|
| 723 | bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e) | 
|---|
| 724 | { | 
|---|
| 725 |   if(actual_tool==NODE_MAP_EDIT) | 
|---|
| 726 |   { | 
|---|
| 727 |     switch(e->type) | 
|---|
| 728 |     { | 
|---|
| 729 |       case GDK_BUTTON_PRESS: | 
|---|
| 730 |         { | 
|---|
| 731 |           //for determine, whether it was a node | 
|---|
| 732 |           Node clicked_node=INVALID; | 
|---|
| 733 |  | 
|---|
| 734 |           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); | 
|---|
| 735 |           active_item=(get_item_at(clicked_x, clicked_y)); | 
|---|
| 736 |  | 
|---|
| 737 |           //find the activated item between texts | 
|---|
| 738 |           for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 739 |           { | 
|---|
| 740 |             //at the same time only one can be active | 
|---|
| 741 |             if(nodetextmap[i]==active_item) | 
|---|
| 742 |             { | 
|---|
| 743 |               clicked_node=i; | 
|---|
| 744 |             } | 
|---|
| 745 |           } | 
|---|
| 746 |  | 
|---|
| 747 |           //if there was not, search for it between nodes | 
|---|
| 748 |           if(clicked_node==INVALID) | 
|---|
| 749 |           { | 
|---|
| 750 |             for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 751 |             { | 
|---|
| 752 |               //at the same time only one can be active | 
|---|
| 753 |               if(nodesmap[i]==active_item) | 
|---|
| 754 |               { | 
|---|
| 755 |                 clicked_node=i; | 
|---|
| 756 |               } | 
|---|
| 757 |             } | 
|---|
| 758 |           } | 
|---|
| 759 |  | 
|---|
| 760 |           //if it was really a node... | 
|---|
| 761 |           if(clicked_node!=INVALID) | 
|---|
| 762 |           { | 
|---|
| 763 |             // the id map is not editable | 
|---|
| 764 |             if (nodemap_to_edit == "label") return 0; | 
|---|
| 765 |  | 
|---|
| 766 |             //and there is activated map | 
|---|
| 767 |             if(nodetextmap[clicked_node]->property_text().get_value()!="") | 
|---|
| 768 |             { | 
|---|
| 769 |               //activate the general variable for it | 
|---|
| 770 |               active_node=clicked_node; | 
|---|
| 771 |  | 
|---|
| 772 |               //create a dialog | 
|---|
| 773 |               Gtk::Dialog dialog("Edit value", true); | 
|---|
| 774 |               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); | 
|---|
| 775 |               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT); | 
|---|
| 776 |               Gtk::VBox* vbox = dialog.get_vbox(); | 
|---|
| 777 |               Gtk::SpinButton spin(0.0, 4); | 
|---|
| 778 |               spin.set_increments(1.0, 10.0); | 
|---|
| 779 |               spin.set_range(-1000000.0, 1000000.0); | 
|---|
| 780 |               spin.set_numeric(true); | 
|---|
| 781 |               vbox->add(spin); | 
|---|
| 782 |               spin.show(); | 
|---|
| 783 |               switch (dialog.run()) | 
|---|
| 784 |               { | 
|---|
| 785 |                 case Gtk::RESPONSE_NONE: | 
|---|
| 786 |                 case Gtk::RESPONSE_CANCEL: | 
|---|
| 787 |                   break; | 
|---|
| 788 |                 case Gtk::RESPONSE_ACCEPT: | 
|---|
| 789 |                   double new_value = spin.get_value(); | 
|---|
| 790 |                   (*(mytab.mapstorage).nodemap_storage[nodemap_to_edit])[active_node] = | 
|---|
| 791 |                     new_value; | 
|---|
| 792 |                   std::ostringstream ostr; | 
|---|
| 793 |                   ostr << new_value; | 
|---|
| 794 |                   nodetextmap[active_node]->property_text().set_value( | 
|---|
| 795 |                       ostr.str()); | 
|---|
| 796 |                   //mapwin.updateNode(active_node); | 
|---|
| 797 | //                   mapwin.updateNode(Node(INVALID)); | 
|---|
| 798 |                   propertyUpdate(Node(INVALID)); | 
|---|
| 799 |               } | 
|---|
| 800 |             } | 
|---|
| 801 |           } | 
|---|
| 802 |           break; | 
|---|
| 803 |         } | 
|---|
| 804 |       default: | 
|---|
| 805 |         break; | 
|---|
| 806 |     } | 
|---|
| 807 |   } | 
|---|
| 808 |   return false;   | 
|---|
| 809 | } | 
|---|
| 810 |  | 
|---|
| 811 | void GraphDisplayerCanvas::deleteItem(Node node_to_delete) | 
|---|
| 812 | { | 
|---|
| 813 |   delete(nodetextmap[node_to_delete]); | 
|---|
| 814 |   delete(nodesmap[node_to_delete]); | 
|---|
| 815 |   (mytab.mapstorage).graph.erase(node_to_delete); | 
|---|
| 816 | } | 
|---|
| 817 |  | 
|---|
| 818 | void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete) | 
|---|
| 819 | { | 
|---|
| 820 |   delete(edgetextmap[edge_to_delete]); | 
|---|
| 821 |   delete(edgesmap[edge_to_delete]); | 
|---|
| 822 |   (mytab.mapstorage).graph.erase(edge_to_delete); | 
|---|
| 823 | } | 
|---|
| 824 |  | 
|---|
| 825 | void GraphDisplayerCanvas::textReposition(xy<double> new_place) | 
|---|
| 826 | { | 
|---|
| 827 |   new_place+=(xy<double>(10,10)); | 
|---|
| 828 |   edgetextmap[forming_edge]->property_x().set_value(new_place.x); | 
|---|
| 829 |   edgetextmap[forming_edge]->property_y().set_value(new_place.y); | 
|---|
| 830 | } | 
|---|
| 831 |  | 
|---|
| 832 | void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on) | 
|---|
| 833 | { | 
|---|
| 834 |   if(on) | 
|---|
| 835 |     { | 
|---|
| 836 |       if(forming_edge!=INVALID) | 
|---|
| 837 |         { | 
|---|
| 838 |           std::cerr << "ERROR!!!! Valid edge found!" << std::endl; | 
|---|
| 839 |         } | 
|---|
| 840 |       else | 
|---|
| 841 |         { | 
|---|
| 842 |           for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) | 
|---|
| 843 |             { | 
|---|
| 844 |               if(edgesmap[i]==active_bre) | 
|---|
| 845 |                 { | 
|---|
| 846 |                   forming_edge=i; | 
|---|
| 847 |                 } | 
|---|
| 848 |             } | 
|---|
| 849 |         } | 
|---|
| 850 |     } | 
|---|
| 851 |   else | 
|---|
| 852 |     { | 
|---|
| 853 |       if(forming_edge!=INVALID) | 
|---|
| 854 |         { | 
|---|
| 855 |           forming_edge=INVALID; | 
|---|
| 856 |         } | 
|---|
| 857 |       else | 
|---|
| 858 |         { | 
|---|
| 859 |           std::cerr << "ERROR!!!! Invalid edge found!" << std::endl; | 
|---|
| 860 |         } | 
|---|
| 861 |     } | 
|---|
| 862 | } | 
|---|