The attached patch and two new files (app/select.h and app/select.c)
implement a new submenu on the display (right-button) menu, similar to the
Select menu in Gimp.  It allows selecting all, none, invert, same type or
connected (one step transitive), and allows setting the selection mechanism
(currently only for drag-select) to either replace, union, intersection,
removal or inversal.  These five ought to be radiomenuitems, but I haven't
found the proper docs on doing those. (There's also a Gnome menu
corresponding to the Toolbox items, but I haven't gotten that finished
yet, and there's a fix of a memory leak from drag select.)

-Lars

[My apologies if the charset is odd.  Gnus is misbehaving.]

-- 
Lars Clausen (http://shasta.cs.uiuc.edu/~lrclause) | H�rdgrim of Numenor
"I do not agree with a word that you say, but I    | Retainer of Sir Kegg
will defend to the death your right to say it."    |   of Westfield
    --Evelyn Beatrice Hall paraphrasing Voltaire   | Chaos Berserker of Khorne

===File ~/src/dia/lrclause.diff.gz.uue======================
begin 664 lrclause.diff.gz
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
==Y9L2KH%+QIZND?M4MK6HL#XPW\!C/LW@'TN````
`
end
============================================================

===File ~/src/dia/app/select.c==============================
/* Dia -- an diagram creation/manipulation program
 * Copyright (C) 1998 Alexander Larsson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/* select.c -- callbacks to implement the Select menu */
#include <assert.h>

#include "select.h"
#include "menu.h"
#include "intl.h"

enum SelectionStyle selection_style = SELECT_REPLACE;

void
select_all_callback(GtkWidget *widget, gpointer data) {
  Diagram *dia;
  GList *objects;

  dia = ddisplay_active()->diagram;

  objects = dia->data->active_layer->objects;

  while (objects != NULL) {
    Object *obj = (Object *)objects->data;
    
    if (!diagram_is_selected(dia, obj))
      diagram_select(dia, obj);
    
    objects = g_list_next(objects);
  }

  diagram_update_menu_sensitivity(dia);
  object_add_updates_list(dia->data->selected, dia);
  diagram_flush(dia);
}

void
select_none_callback(GtkWidget *widget, gpointer data) {
  Diagram * dia = ddisplay_active()->diagram;

  diagram_remove_all_selected(dia, TRUE);

  diagram_update_menu_sensitivity(dia);
  object_add_updates_list(dia->data->selected, dia);
  diagram_flush(dia);
}

void
select_invert_callback(GtkWidget *widget, gpointer data) {
  Diagram *dia;
  GList *objects, *tmp;

  dia = ddisplay_active()->diagram;

  tmp = dia->data->active_layer->objects;

  for (; tmp != NULL; tmp = g_list_next(tmp)) {
    Object *obj = (Object *)tmp->data;
    
    if (!diagram_is_selected(dia, obj))
      diagram_select(dia, obj);
    else
      diagram_unselect_object(dia, obj);
  }

  diagram_update_menu_sensitivity(dia);
  object_add_updates_list(dia->data->selected, dia);
  diagram_flush(dia);
  
}

void
select_connected_callback(GtkWidget *widget, gpointer data) {
  Diagram *dia = ddisplay_active()->diagram;
  GList *objects, *tmp;

  objects = dia->data->selected;

  for (tmp = objects; tmp != NULL; tmp = g_list_next(tmp)) {
    Object *obj = (Object *)tmp->data;
    int i;

    for (i = 0; i < obj->num_handles; i++) {
      Handle *handle = obj->handles[i];
      
      if (handle->connected_to != NULL) {
        if (!diagram_is_selected(dia, handle->connected_to->object)) {
          diagram_select(dia, handle->connected_to->object);
        }
      }      
    }
  }

  for (tmp = objects; tmp != NULL; tmp = tmp->next) {
    Object *obj = (Object *)tmp->data;
    int i;

    for (i = 0; i < obj->num_connections; i++) {
      ConnectionPoint *connection = obj->connections[i];
      GList *conns = connection->connected;

      for (; conns != NULL; conns = g_list_next(conns)) {
        Object *obj2 = (Object *)conns->data;

        if (!diagram_is_selected(dia, obj2)) {
          diagram_select(dia, obj2);
        }
      }      
    }
  }

  diagram_update_menu_sensitivity(dia);
  object_add_updates_list(dia->data->selected, dia);
  diagram_flush(dia);
}

void
select_same_type_callback(GtkWidget *widget, gpointer data) {
  /* For now, do a brute force version:  Check vs. all earlier selected.
     Later, we should really sort the selecteds first to avoid n^2 */
  Diagram *dia;
  GList *objects, *tmp, *tmp2;

  dia = ddisplay_active()->diagram;

  tmp = dia->data->active_layer->objects;

  objects = dia->data->selected;

  for (; tmp != NULL; tmp = g_list_next(tmp)) {
    Object *obj = (Object *)tmp->data;

    if (!diagram_is_selected(dia, obj)) {
      for (tmp2 = objects; tmp2 != NULL; tmp2 = g_list_next(tmp2)) {
        Object *obj2 = (Object *)tmp2->data;
       
        if (obj->type == obj2->type) {
          diagram_select(dia, obj);
          break;
        }
      }
    }
  }

  diagram_update_menu_sensitivity(dia);
  object_add_updates_list(dia->data->selected, dia);
  diagram_flush(dia);
}

void
select_style_callback(GtkWidget *widget, gpointer data) {
  static GtkCheckMenuItem *replace_item;
  static GtkCheckMenuItem *union_item;
  static GtkCheckMenuItem *intersect_item;
  static GtkCheckMenuItem *remove_item;
  static GtkCheckMenuItem *invert_item;
  static GString *path;
  static int initialized = 0;
  char *display = "<Display>";

  selection_style = (int)data;
  
  if (initialized == 0) {
#   ifdef GNOME
    if (ddisplay_active () == NULL) return;
#   endif

    /* Now do the radio button thing */
    path = g_string_new ("<Display>");
    g_string_append (path,_("/Select/Replace"));
    replace_item = (GtkCheckMenuItem *)menus_get_item_from_path(path->str);
    g_string_append (g_string_assign(path, display),_("/Select/Union"));
    union_item = (GtkCheckMenuItem *)menus_get_item_from_path(path->str);
    g_string_append (g_string_assign(path, display),_("/Select/Intersect"));
    intersect_item = (GtkCheckMenuItem *)menus_get_item_from_path(path->str);
    g_string_append (g_string_assign(path, display),_("/Select/Remove"));
    remove_item = (GtkCheckMenuItem *)menus_get_item_from_path(path->str);
    g_string_append (g_string_assign(path, display),_("/Select/Invert"));
    invert_item = (GtkCheckMenuItem *)menus_get_item_from_path(path->str);
    g_string_free(path, FALSE);
    initialized = 1;
  }

  /* Ok, this should really be done with a radiomenu, but I don't have
     any docs on that */

  if ((selection_style == SELECT_REPLACE)^(replace_item->active))
    gtk_check_menu_item_toggled(replace_item);
  if ((selection_style == SELECT_UNION)^(union_item->active))
    gtk_check_menu_item_toggled(union_item);
  if ((selection_style == SELECT_INTERSECTION)^(intersect_item->active))
    gtk_check_menu_item_toggled(intersect_item);
  if ((selection_style == SELECT_REMOVE)^(remove_item->active))
    gtk_check_menu_item_toggled(remove_item);
  if ((selection_style == SELECT_INVERT)^(invert_item->active))
    gtk_check_menu_item_toggled(invert_item);
}

============================================================

===File ~/src/dia/app/select.h==============================
/* Dia -- an diagram creation/manipulation program
 * Copyright (C) 1998 Alexander Larsson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#ifndef SELECT_H
#define SELECT_H

#include "diagram.h"
#include "display.h"

enum SelectionStyle {SELECT_REPLACE, SELECT_UNION, 
                     SELECT_INTERSECTION, SELECT_REMOVE, SELECT_INVERT};

extern enum SelectionStyle selection_style;

void select_all_callback(GtkWidget *widget, gpointer data);
void select_none_callback(GtkWidget *widget, gpointer data);
void select_invert_callback(GtkWidget *widget, gpointer data);
void select_connected_callback(GtkWidget *widget, gpointer data);
void select_same_type_callback(GtkWidget *widget, gpointer data);
void select_style_callback(GtkWidget *widget, gpointer data);

#endif
============================================================

Reply via email to