Пример #1
0
static void
_object_remove(DiagramData      *dia,
	       Layer            *layer,
               DiaObject        *obj,
	       DiagramTreeModel *dtm)
{
  GtkTreePath *path;
  GtkTreeIter _iter;
  GtkTreeIter *iter = &_iter;
  gboolean last_child = layer_object_count (layer) == 0;

  g_return_if_fail (DIA_DIAGRAM(dia) != NULL);
  
  NODE_DIAGRAM(iter) = dia;
  NODE_LAYER(iter)   = layer;
  NODE_OBJECT(iter)  = obj;

  path = _dtm_get_path (GTK_TREE_MODEL (dtm), iter);
  gtk_tree_model_row_deleted (GTK_TREE_MODEL (dtm), path);
  gtk_tree_path_free (path);
  /* enforce update - but the arrow on layer does not vanish */
  if (last_child) {
    NODE_OBJECT(iter)  = NULL;
    path = _dtm_get_path (GTK_TREE_MODEL (dtm), iter);
    gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (dtm), path, iter);
    gtk_tree_path_free (path);
  }
}
Пример #2
0
/* listen on the diagram for object add/remove */
static void
_object_add (DiagramData      *dia,
	     Layer            *layer,
             DiaObject        *obj,
	     DiagramTreeModel *dtm)
{
  GtkTreePath *path;
  GtkTreeIter _iter;
  GtkTreeIter *iter = &_iter;
  /* a bit backward: the first child is in the diagram, but not the tree yet */
  gboolean had_child = layer_object_count (layer) > 1;

  g_return_if_fail (DIA_DIAGRAM(dia) != NULL);

  NODE_DIAGRAM(iter) = dia;
  NODE_LAYER(iter)   = layer;
  NODE_OBJECT(iter)  = obj;


  /* FIXME: this may get called before the layer is added to the tree */
  path = _dtm_get_path (GTK_TREE_MODEL (dtm), iter);
  if (path) {
    gtk_tree_model_row_inserted (GTK_TREE_MODEL (dtm), path, iter);
    /* enforce update */
    if (!had_child && gtk_tree_path_up (path))
      gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (dtm), path, &_iter);
    gtk_tree_path_free (path);
  }
}
Пример #3
0
/* SORTABLE 
 * Wrapper around the original model to allow sorting by various columns IDs
 */
static gint
cmp_diagram (GtkTreeIter  *a,
	     GtkTreeIter  *b)
{
  DiagramData *pa = NODE_DIAGRAM(a), *pb = NODE_DIAGRAM(b);
  gchar *na, *nb;
  gint ret;
  if (pa == pb)
    return 0;
  na = diagram_get_name (DIA_DIAGRAM(pa));
  nb = diagram_get_name (DIA_DIAGRAM(pa));
  if (!na || !nb)
    return (na > nb) ? -1 : 1;
  ret = strcmp (na, nb);
  g_free (na);
  g_free (nb);
  return ret;
}
Пример #4
0
/** Connects a python function to a signal.
 *  @param self The PyDiaDiagram this is a method of.
 *  @param args A tuple containing the arguments, a str for signal name
 *  and a callable object (like a function)
 */
static PyObject *
PyDiaDiagram_ConnectAfter(PyDiaDiagram *self, PyObject *args)
{
    PyObject *func;
    char *signal;

    /* Check arguments */
    if (!PyArg_ParseTuple(args, "sO:connect_after",&signal,&func))
        return NULL;

    /* Check that the arg is callable */
    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError, "Second parameter must be callable");
        return NULL;
    }

    /* check if the signals name is valid */
    if ( strcmp("removed",signal) == 0 || strcmp("selection_changed",signal) == 0) {

        Py_INCREF(func); /* stay alive, where to kill ?? */

        /* connect to signal after by signal name */
        if (strcmp("removed",signal) == 0)
        {
            g_signal_connect_after(DIA_DIAGRAM(self->dia),"removed",G_CALLBACK(PyDiaDiagram_CallbackRemoved), func);
        }
        
        if (strcmp("selection_changed",signal) == 0)
        {
            g_signal_connect_after(DIA_DIAGRAM(self->dia),"selection_changed",G_CALLBACK(PyDiaDiagram_CallbackSelectionChanged), func);
        }
 
        Py_INCREF(Py_None);
        return Py_None;
    }
    else {
            PyErr_SetString(PyExc_TypeError, "Wrong signal name");
            return NULL;
    }
}
Пример #5
0
static void
diagram_finalize(GObject *object) 
{
  Diagram *dia = DIA_DIAGRAM(object);

  assert(dia->displays==NULL);
  
  if (dia->filename)
    g_free(dia->filename);
  dia->filename = NULL;

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
Пример #6
0
static void
_dtm_init (DiagramTreeModel *dtm)
{
  /* connect to intersting state changes */
  g_signal_connect (G_OBJECT (dia_application_get ()),
                    "diagram_add", G_CALLBACK (_diagram_add), dtm);
  g_signal_connect (G_OBJECT (dia_application_get ()),
                    "diagram_change", G_CALLBACK (_diagram_change), dtm);
  g_signal_connect (G_OBJECT(dia_application_get ()),
                    "diagram_remove", G_CALLBACK (_diagram_remove), dtm);
  /* also connect to every already existing diagram */
  {
    GList *list =  dia_open_diagrams();

    while (list) {
      _dtm_listen_on_diagram (dtm, DIA_DIAGRAM(list->data));
      list = g_list_next (list);
    }
  }
}
Пример #7
0
static void
_object_remove(DiagramData      *dia,
	       Layer            *layer,
               DiaObject        *obj,
	       DiagramTreeModel *dtm)
{
  GtkTreePath *path;
  GtkTreeIter _iter;
  GtkTreeIter *iter = &_iter;

  g_return_if_fail (DIA_DIAGRAM(dia) != NULL);
  
  NODE_DIAGRAM(iter) = dia;
  NODE_LAYER(iter)   = layer;
  NODE_OBJECT(iter)  = obj;

  path = _dtm_get_path (GTK_TREE_MODEL (dtm), iter);
  gtk_tree_model_row_deleted (GTK_TREE_MODEL (dtm), path);
  gtk_tree_path_free (path);
}
Пример #8
0
static void
diagram_dispose (GObject *object)
{
  Diagram *dia = DIA_DIAGRAM(object);

  assert(dia->displays==NULL);
  
  if (g_list_index(open_diagrams, dia) >= 0) {
    dia_diagram_remove(dia);

    open_diagrams = g_list_remove(open_diagrams, dia);
    layer_dialog_update_diagram_list();
  }

  if (dia->undo)
    undo_destroy(dia->undo);
  dia->undo = NULL;
  
  diagram_cleanup_autosave(dia);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
Пример #9
0
static void
_dtm_get_value (GtkTreeModel *tree_model,
		GtkTreeIter  *iter,
		gint          column,
		GValue       *value)
{

  switch (column) {
  case DIAGRAM_COLUMN :
    g_value_init (value, G_TYPE_OBJECT);
    g_value_set_object (value, NODE_DIAGRAM(iter));
    break;
  case LAYER_COLUMN :
    g_value_init (value, G_TYPE_POINTER);
    g_value_set_pointer (value, NODE_LAYER(iter));
    break;
  case OBJECT_COLUMN :
    g_value_init (value, G_TYPE_POINTER);
    g_value_set_pointer (value, NODE_OBJECT(iter));
    break;
  case NAME_COLUMN :
    g_value_init (value, G_TYPE_STRING);
    /* deduce the requested name from the iter */
    if (NODE_OBJECT(iter))
      g_value_set_string (value, object_get_displayname (NODE_OBJECT (iter)));
    else if (NODE_LAYER(iter))
      g_value_set_string (value, layer_get_name (NODE_LAYER (iter)));
    else if (NODE_DIAGRAM(iter))
      g_value_set_string (value, diagram_get_name (DIA_DIAGRAM(NODE_DIAGRAM(iter))));
    else /* warn on it? */
      g_value_set_string (value, NULL);
    break;
  default :
    g_assert_not_reached ();
  }
}
Пример #10
0
/* listen on the diagram for object add/remove */
static void
_object_add (DiagramData      *dia,
	     Layer            *layer,
             DiaObject        *obj,
	     DiagramTreeModel *dtm)
{
  GtkTreePath *path;
  GtkTreeIter _iter;
  GtkTreeIter *iter = &_iter;

  g_return_if_fail (DIA_DIAGRAM(dia) != NULL);

  NODE_DIAGRAM(iter) = dia;
  NODE_LAYER(iter)   = layer;
  NODE_OBJECT(iter)  = obj;


  /* FIXME: this may get called before the layer is added to the tree */
  path = _dtm_get_path (GTK_TREE_MODEL (dtm), iter);
  if (path) {
    gtk_tree_model_row_inserted (GTK_TREE_MODEL (dtm), path, iter);
    gtk_tree_path_free (path);
  }
}
Пример #11
0
static PyObject *
PyDiaDiagramData_GetAttr(PyDiaDiagramData *self, gchar *attr)
{
    Diagram *diagram = DIA_DIAGRAM(self->data);

    if (!strcmp(attr, "__members__"))
	return Py_BuildValue("[ssssssssssss]",
                           "extents", "bg_color", "paper",
                           "layers", "active_layer", 
                           "grid_width", "grid_visible", 
                           "hguides", "vguides",
                           "layers", "active_layer",
                           "selected" );
    else if (!strcmp(attr, "extents"))
      return PyDiaRectangle_New(&self->data->extents, NULL);
    else if (!strcmp(attr, "bg_color")) {
      return PyDiaColor_New (&(self->data->bg_color));
    }
    else if (!strcmp(attr, "layers")) {
	guint i, len = self->data->layers->len;
	PyObject *ret = PyTuple_New(len);

	for (i = 0; i < len; i++)
	    PyTuple_SetItem(ret, i, PyDiaLayer_New(
			g_ptr_array_index(self->data->layers, i)));
	return ret;
    } else if (!strcmp(attr, "active_layer")) {
	return PyDiaLayer_New(self->data->active_layer);
    } else if (!strcmp(attr, "paper")) {
        return PyDiaPaperinfo_New (&self->data->paper);
    }
    else if (diagram && !strcmp(attr, "grid_width")) 
      return Py_BuildValue("(dd)", diagram->grid.width_x, diagram->grid.width_y);
    else if (diagram && !strcmp(attr, "grid_visible")) 
      return Py_BuildValue("(ii)", diagram->grid.visible_x, diagram->grid.visible_y);
    else if (diagram && !strcmp(attr, "hguides")) {
      int len = diagram->guides.nhguides;
      PyObject *ret = PyTuple_New(len);
      int i;
      for (i = 0; i < len; i++)
        PyTuple_SetItem(ret, i, PyFloat_FromDouble(diagram->guides.hguides[i]));
      return ret;
    }
    else if (diagram && !strcmp(attr, "vguides")) {
      int len = diagram->guides.nvguides;
      PyObject *ret = PyTuple_New(len);
      int i;
      for (i = 0; i < len; i++)
        PyTuple_SetItem(ret, i, PyFloat_FromDouble(diagram->guides.vguides[i]));
      return ret;
    }
    else if (!strcmp(attr, "layers")) {
	guint i, len = self->data->layers->len;
	PyObject *ret = PyTuple_New(len);

	for (i = 0; i < len; i++)
	    PyTuple_SetItem(ret, i, PyDiaLayer_New(
			g_ptr_array_index(self->data->layers, i)));
	return ret;
    }
    else if (!strcmp(attr, "active_layer")) {
      return PyDiaLayer_New(self->data->active_layer);
    }
    else if (!strcmp(attr, "selected")) {
	PyObject *ret;
	GList *tmp;
	gint i;

	ret = PyTuple_New(g_list_length(self->data->selected));
	for (i = 0, tmp = self->data->selected; tmp; i++, tmp = tmp->next)
	    PyTuple_SetItem(ret, i, PyDiaObject_New((DiaObject *)tmp->data));
	return ret;
    }

    return Py_FindMethod(PyDiaDiagramData_Methods, (PyObject *)self, attr);
}
Пример #12
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;
}