dia r4023 - in trunk: . app



Author: hans
Date: Mon May 12 13:50:55 2008
New Revision: 4023
URL: http://svn.gnome.org/viewvc/dia?rev=4023&view=rev

Log:
2008-05-12  Hans Breuer  <hans breuer org>

	* app/find-and-replace.c : replace (al) part is working, too.
	


Modified:
   trunk/ChangeLog
   trunk/app/find-and-replace.c

Modified: trunk/app/find-and-replace.c
==============================================================================
--- trunk/app/find-and-replace.c	(original)
+++ trunk/app/find-and-replace.c	Mon May 12 13:50:55 2008
@@ -29,8 +29,13 @@
 #include "diagram.h"
 #include "display.h"
 #include "object.h"
+#include "object_ops.h"
+#include "connectionpoint_ops.h"
+#include "undo.h"
 
 #include "find-and-replace.h"
+/* messing with property internals */
+#include "propinternals.h"
 
 enum {
   RESPONSE_FIND = -20,
@@ -53,27 +58,81 @@
   gboolean seen_last;
 } SearchData;
 
-static gboolean
-_matches (DiaObject *obj, const SearchData *sd)
+/*! Match and possibly modify the given objects property */
+Property *
+_match_string_prop (DiaObject *obj, const SearchData *sd, const gchar *replacement)
 {
-  gchar* name = object_get_displayname (obj);
+  Property *prop;
+  gchar   **name;
   gboolean ret = FALSE;
+  gchar    *repl = NULL;
 
-  if (sd->flags & MATCH_CASE)
-    ret = strstr (name, sd->key) != NULL;
-  else {
-    gchar *s1 = g_utf8_casefold (name, -1);
+  if ((prop = object_prop_by_name(obj, "name")) != NULL)
+    name = &((StringProperty *)prop)->string_data;
+  else if ((prop = object_prop_by_name(obj, "text")) != NULL)
+    name = &((TextProperty *)prop)->text_data;
+
+  if (!prop)
+    return NULL;
+
+  /* search part */
+  if (sd->flags & MATCH_CASE) {
+    const gchar *p = strstr (*name, sd->key);
+    ret = p != NULL;
+    if (p && replacement) {
+      gchar *a = g_strndup (*name, p - *name);
+      gchar *b = g_strdup (p + strlen(sd->key));
+      repl = g_strdup_printf ("%s%s%s", a, replacement, b);
+      g_free (a);
+      g_free (b);
+    }
+  } else {
+    gchar *s1 = g_utf8_casefold (*name, -1);
     gchar *s2 = g_utf8_casefold (sd->key, -1);
-    ret = strstr (s1, s2) != NULL;
+    const gchar *p = strstr (s1, s2);
+    ret = p != NULL;
+    if (p && replacement) {
+      gchar *a = g_strndup (*name, p - s1);
+      gchar *b = g_strdup (*name + strlen(a) + strlen(sd->key));
+      repl = g_strdup_printf ("%s%s%s", a, replacement, b);
+      g_free (a);
+      g_free (b);
+    }
     g_free (s1);
     g_free (s2);
   }
 
   if (sd->flags & MATCH_WORD)
-    ret = (ret && strlen(name) == strlen(sd->key));
+    ret = (ret && strlen(*name) == strlen(sd->key));
+
+  /* replace part */
+  if (ret && replacement) {
+    g_free (*name);
+    *name = repl;
+  } else {
+    g_free (repl);
+  }
+  
+  if (ret)
+    return prop;
+    
+  prop->ops->free(prop);
+  return NULL;
+}
 
-  g_free (name);
-  return ret;
+static gboolean
+_matches (DiaObject *obj, const SearchData *sd)
+{
+  Property *prop = NULL;
+
+  if (!obj)
+    return FALSE;
+
+  prop = _match_string_prop (obj, sd, NULL);
+  if (prop)
+    prop->ops->free(prop);
+
+  return (prop != NULL);    
 }
 
 static void
@@ -94,6 +153,34 @@
   }
 }
 
+static gboolean
+_replace (DiaObject *obj, const SearchData *sd, const char *replacement)
+{
+  ObjectChange *obj_change;
+  Property *prop;
+  GPtrArray *plist;
+
+  prop = _match_string_prop (obj, sd, replacement);
+  if (!prop)
+    return FALSE;
+    
+  plist = prop_list_from_single (prop);
+  obj_change = object_apply_props (obj, plist);
+  prop_list_free (plist);
+
+  if (obj_change)
+    undo_object_change(sd->diagram, obj, obj_change);
+    
+  object_add_updates(obj, sd->diagram);
+  diagram_update_connections_object(sd->diagram, obj, TRUE);
+  diagram_modified(sd->diagram);
+  diagram_object_modified(sd->diagram, obj);
+  diagram_update_extents(sd->diagram);
+  diagram_flush(sd->diagram);
+  
+  return TRUE;
+}
+
 static gint
 fnr_respond (GtkWidget *widget, gint response_id, gpointer data)
 {
@@ -132,10 +219,38 @@
     break;
   case RESPONSE_REPLACE :
     replace = gtk_entry_get_text (g_object_get_data (G_OBJECT (widget), "replace-entry"));
-    g_print ("Replace: %s\n", replace);
+    sd.key = search;
+    sd.last = g_object_get_data (G_OBJECT (widget), "last-found");
+    if (!_matches (sd.last, &sd)) {
+      sd.last = NULL; /* reset if we start a new search */
+      data_foreach_object (ddisp->diagram->data, find_func, &sd);
+    }
+    sd.last = sd.found ? sd.found : sd.first;
+    g_object_set_data (G_OBJECT (widget), "last-found", sd.last);
+    if (sd.last) {
+      _replace (sd.last, &sd, replace);
+      undo_set_transactionpoint(ddisp->diagram->undo);
+    }
+    g_object_set_data (G_OBJECT (widget), "last-found", sd.last);
     break;
   case RESPONSE_REPLACE_ALL :
-    break;
+    replace = gtk_entry_get_text (g_object_get_data (G_OBJECT (widget), "replace-entry"));
+    sd.key = search;
+    sd.last = g_object_get_data (G_OBJECT (widget), "last-found");
+    do {
+      if (!_matches (sd.last, &sd)) {
+        sd.last = NULL; /* reset if we start a new search */
+	sd.first = NULL;
+        data_foreach_object (ddisp->diagram->data, find_func, &sd);
+      }
+      sd.last = sd.found ? sd.found : sd.first;
+      if (sd.last)
+        if (!_replace (sd.last, &sd, replace))
+	  sd.last = NULL;
+    } while (sd.last);
+    g_object_set_data (G_OBJECT (widget), "last-found", sd.last);
+    undo_set_transactionpoint(ddisp->diagram->undo);
+    break;
   default:
     gtk_widget_hide (widget);
   }
@@ -161,8 +276,6 @@
 		   G_CALLBACK(gtk_widget_hide), NULL);
   g_signal_connect(GTK_OBJECT(dialog), "delete_event",
 		   G_CALLBACK(gtk_true), NULL);
-  g_signal_connect(GTK_OBJECT(dialog), "destroy",
-		   G_CALLBACK(gtk_widget_destroyed), &dialog);
 
   vbox = GTK_DIALOG(dialog)->vbox;
 
@@ -249,15 +362,22 @@
   /* no static var, instead we are attaching the dialog to the diplay shell */
   dialog = g_object_get_data (G_OBJECT (ddisp->shell), "edit-replace-dialog");
   if (!dialog) {
+    GtkWidget *button;
     dialog = gtk_dialog_new_with_buttons (
-		_("Replace"), 
+		_("Replace"),
 		GTK_WINDOW (ddisp->shell), GTK_DIALOG_DESTROY_WITH_PARENT,
 		GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-		_("Replace _All"), RESPONSE_REPLACE_ALL,
-		GTK_STOCK_FIND_AND_REPLACE, RESPONSE_REPLACE,
-		GTK_STOCK_FIND, RESPONSE_FIND,
+		_("Replace _All"), RESPONSE_REPLACE_ALL,
 		NULL);
-    
+    /* not adding the button in the list above to modify it's text; 
+     * the default "Find and Replace" is just too long for my taste ;) 
+     */
+    button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Replace"), RESPONSE_REPLACE);
+    gtk_button_set_image (GTK_BUTTON (button), 
+                          gtk_image_new_from_stock (GTK_STOCK_FIND_AND_REPLACE, GTK_ICON_SIZE_BUTTON));
+
+    gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_FIND, RESPONSE_FIND);
+
     fnr_dialog_setup_common (dialog, TRUE, ddisp);
   }
   g_object_set_data (G_OBJECT (ddisp->shell), "edit-replace-dialog", dialog);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]