Пример #1
0
/*!
 * \brief Create a new diagram data object only containing the selected objects
 * \memberof _DiagramData
 */
DiagramData *
diagram_data_clone_selected (DiagramData *data)
{
  DiagramData *clone;
  Layer *dest_layer;
  GList *sorted;

  clone = g_object_new (DIA_TYPE_DIAGRAM_DATA, NULL);
  
  clone->extents = data->extents;
  clone->bg_color = data->bg_color;
  clone->paper = data->paper; /* so ugly */
  clone->paper.name = g_strdup (data->paper.name);
  clone->is_compressed = data->is_compressed;

  /* the selection - if any - can only be on the active layer */
  dest_layer = g_ptr_array_index(clone->layers, 0);
  g_free (dest_layer->name);
  dest_layer->name = layer_get_name (data->active_layer);

  sorted = data_get_sorted_selected (data);
  dest_layer->objects = object_copy_list (sorted);
  g_list_free (sorted);
  dest_layer->visible = data->active_layer->visible;
  dest_layer->connectable = data->active_layer->connectable;
  
  data_update_extents (clone);
  
  return clone;
}
Пример #2
0
dia::Objects&
dia::DiagramData::get_sorted_selected () const
{
    if (_selected)
        delete _selected;

    static GList* list = data_get_sorted_selected(self);
    const_cast< DiagramData* >(this)->_selected = new dia::Objects (&list);
    return *_selected;
}
Пример #3
0
static PyObject *
PyDiaDiagramData_GetSortedSelected(PyDiaDiagramData *self, PyObject *args)
{
    GList *list, *tmp;
    PyObject *ret;
    guint i, len;

    if (!PyArg_ParseTuple(args, ":DiagramData.get_sorted_selected"))
	return NULL;
    list = data_get_sorted_selected(self->data);

    len = g_list_length (list);
    ret = PyTuple_New(len);

    for (i = 0, tmp = list; tmp; i++, tmp = tmp->next)
	PyTuple_SetItem(ret, i, PyDiaObject_New((DiaObject *)tmp->data));
    g_list_free(list);
    return ret;
}
Пример #4
0
GList *
diagram_get_sorted_selected(Diagram *dia)
{
  return data_get_sorted_selected(dia->data);
}
Пример #5
0
/*!
 * \brief Calback function invoking layout algorithms from Dia's menu
 * \ingroup LayoutPlugin
 */
static ObjectChange *
layout_callback (DiagramData *data,
                 const gchar *filename,
                 guint flags, /* further additions */
                 void *user_data,
		 GraphCreateFunc func)
{
  ObjectChange *changes = NULL;
  GList *nodes = NULL, *edges = NULL, *list;
  const char *algorithm = (const char*)user_data;

  /* from the selection create two lists */
  list = data_get_sorted_selected (data);
  while (list) {
    DiaObject *o = (DiaObject *)list->data;
    if (!maybe_edge (o))
      nodes = g_list_append (nodes, o);
    //FIXME: neither 1 nor num_handles-1 is guaranteed to be the second connection
    // it entirely depends on the objects implementation
    else if (   o->num_handles > 1 && o->handles[0]->connected_to 
             && (o->handles[1]->connected_to || o->handles[o->num_handles-1]->connected_to))
      edges = g_list_append (edges, o);
    list = g_list_next(list);
  }
  if (g_list_length (edges) < 1 || g_list_length (nodes) < 2) {
    message_warning (_("Please select edges and nodes to layout."));
  } else {
    IGraph *g = func ? func () : NULL;

    if (!g)
      message_error (_("Graph creation failed"));
    else {
      std::vector<double> coords;

      /* transfer nodes and edges */
      for (list = nodes; list != NULL; list = g_list_next(list)) {
        DiaObject *o = (DiaObject *)list->data;
        const Rectangle *bbox = dia_object_get_bounding_box (o);
        g->AddNode (bbox->left, bbox->top, bbox->right, bbox->bottom);
      }
      for (list = edges; list != NULL; list = g_list_next(list)) {
        DiaObject *o = (DiaObject *)list->data;
	DiaObject *src = o->handles[0]->connected_to->object;
	// see above: there is no guarantee ...
	DiaObject *dst = o->handles[1]->connected_to ?
	  o->handles[1]->connected_to->object : o->handles[o->num_handles-1]->connected_to->object;

	if (_obj_get_bends (o, coords))
          g->AddEdge (g_list_index (nodes, src), g_list_index (nodes, dst), &coords[0], coords.size());
	else
          g->AddEdge (g_list_index (nodes, src), g_list_index (nodes, dst), NULL, 0);
      }
      IGraph::eResult res;
      if ((res = g->Layout (algorithm)) != IGraph::SUCCESS) {
	const char *sErr;
	switch (res) {
	case IGraph::NO_MODULE : sErr = _("No such module."); break;
	case IGraph::OUT_OF_MEMORY : sErr = _("Out of memory."); break;
	case IGraph::NO_TREE: sErr = _("Not a tree."); break;
	case IGraph::NO_FOREST: sErr = _("Not a forest."); break;
	case IGraph::FAILED_ALGORITHM: sErr = _("Failed algorithm."); break;
	case IGraph::FAILED_PRECONDITION: sErr = _("Failed precondition."); break;
	case IGraph::CRASHED : sErr = _("OGDF crashed."); break;
	default : sErr = _("Unknown reason"); break;
	}
        message_warning (_("Layout '%s' failed.\n%s"), (const char*)user_data, sErr);
      } else {
        changes = change_list_create ();
	/* transfer back information */
	int n;
	for (n = 0, list = nodes; list != NULL; list = g_list_next (list), ++n) {
	  Point pt;
	  if (g->GetNodePosition (n, &pt.x, &pt.y)) {
	    DiaObject *o = (DiaObject *)list->data;
	    GPtrArray *props = g_ptr_array_new ();
	    
	    //FIXME: can't use "obj_pos", it is not read in usual update_data impementations
	    // "elem_corner" will only work for Element derived classes, but that covers most
	    // of the cases here ...
	    prop_list_add_point (props, "elem_corner", &pt);
	    change_list_add (changes, object_apply_props (o, props));
	  }
	}
	// first update to reuse the connected points
	diagram_update_connections_selection(DIA_DIAGRAM (data));
	/* use edge bends, if any */
	int e;
	for (e = 0, list = edges; list != NULL; list = g_list_next (list), ++e) {
          DiaObject *o = (DiaObject *)list->data;
	  // number of bends / 2 is the number of points
	  int n = g->GetEdgeBends (e, NULL, 0);
	  if (n >= 0) { // with 0 it is just a reset of the exisiting line
	    try {
	      coords.resize (n);
	    } catch (std::bad_alloc& ex) {
	      g_warning ("%s", ex.what());
	      continue;
	    }
	    g->GetEdgeBends (e, &coords[0], n);
	    change_list_add (changes, _obj_set_bends (o, coords));
	  }
	}
	/* update view */
	diagram_update_connections_selection(DIA_DIAGRAM (data));
      }
      g->Release ();
    }
  }
  g_list_free (nodes);
  g_list_free (edges);

  return changes;
}