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

Re: Feature freeze for 0.94 coming up



A few weeks ago I sent this patch providing line wrapping in classes. It's not 
very large, and I would appreciate it much if you could have a look on it and 
possibly include it in 0.94, if you think it's an useful improvement for the 
UML class diagrams.
We needed this in our company to optimize the design of UML diagrams 
containing classes whose methods had much parameters. Since some other users 
seemed to miss this feature in other diagram drawing software, I decided to 
make a patch, so that Dia could get this little advantage over other software 
in this point, too.

Keep up your good work, Dia is the best linux diagramming program.

 M. Tidei



On Thursday 01 July 2004 10:07, larsrc raeder dk wrote:
> In three days, we plan to send out the first prerelease for Dia version
> 0.94.  Any patches with new features that you want to get in should be
> posted before then (a reminder of any that have been posted and not
> applied would not be a bad idea).  After then, we will make 0.94-pre1, and
> only bugfixes will be accepted.
>
> -Lars
> _______________________________________________
> Dia-list mailing list
> Dia-list gnome org
> http://mail.gnome.org/mailman/listinfo/dia-list
> FAQ at http://www.gnome.org/projects/dia/faq.html
> Main page at http://www.gnome.org/projects/dia
diff -urNbB dia-0.93_orig/objects/UML/class.c dia-0.93/objects/UML/class.c
--- dia-0.93_orig/objects/UML/class.c	2004-02-29 21:53:44.000000000 +0100
+++ dia-0.93/objects/UML/class.c	2004-05-13 11:58:21.000000000 +0200
@@ -121,6 +121,10 @@
   N_("Visible Operations"), NULL, NULL },
   { "visible_comments", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
   N_("Visible Comments"), NULL, NULL },
+  { "wrap_operations", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
+  N_("Wrap Operations"), NULL, NULL },
+  { "wrap_after_char", PROP_TYPE_INT, PROP_FLAG_VISIBLE,
+  N_("Wrap after char"), NULL, NULL },
   
   { "attributes", PROP_TYPE_STRINGLIST, PROP_FLAG_DONT_SAVE,
   N_("Attributes"), NULL, NULL }, 
@@ -157,6 +161,8 @@
   { "suppress_operations", PROP_TYPE_INT, offsetof(UMLClass , suppress_operations) },
   { "visible_operations", PROP_TYPE_INT, offsetof(UMLClass , visible_operations) },
   { "visible_comments", PROP_TYPE_INT, offsetof(UMLClass , visible_comments) },
+  { "wrap_operations", PROP_TYPE_INT, offsetof(UMLClass , wrap_operations) },
+  { "wrap_after_char", PROP_TYPE_INT, offsetof(UMLClass , wrap_after_char) },
 
   { "operations", PROP_TYPE_STRINGLIST, offsetof(UMLClass , operations_strings) },
   { "attributes", PROP_TYPE_STRINGLIST, offsetof(UMLClass , attributes_strings) },
@@ -436,6 +441,10 @@
       p.x = x + UMLCLASS_BORDER/2.0 + 0.1;
       p.y = p1.y + 0.1;
 
+      int wrap_pos, last_wrap_pos, ident, wrapping_needed;
+      GList *wrapsublist = NULL;
+      gchar part_opstr[umlclass->max_wrapped_line_width];
+
       i = 0;
       list = umlclass->operations;
       while (list != NULL) {
@@ -454,16 +463,56 @@
           font = umlclass->normal_font;
           font_height = umlclass->font_height;
         }
+
+        wrapping_needed = 0;
         opstr = (gchar*) g_list_nth(umlclass->operations_strings, i)->data;
-        ascent = dia_font_ascent(opstr,
-                                 font,font_height);     
-        p.y += ascent;
+        if( umlclass->wrap_operations == TRUE) {
+          wrapsublist = (GList*)g_list_nth( umlclass->operations_wrappos, i)->data;
+          wrapping_needed = GPOINTER_TO_INT( wrapsublist->data);
+        }
 
+        ascent = dia_font_ascent(opstr, font, font_height);
         renderer_ops->set_font(renderer, font, font_height);
+        
+        if( umlclass->wrap_operations == TRUE && wrapping_needed) {
+          
+          wrapsublist = g_list_next( wrapsublist);
+          ident = GPOINTER_TO_INT( wrapsublist->data);
+          wrapsublist = g_list_next( wrapsublist);
+          wrap_pos = last_wrap_pos = 0;
+          
+          while( wrapsublist != NULL) {
+            
+            wrap_pos = GPOINTER_TO_INT( wrapsublist->data);
+            
+            if( last_wrap_pos == 0) {
+              strncpy( part_opstr, opstr, wrap_pos);  
+              memset( part_opstr+wrap_pos, '\0', 1);
+            } else {  
+              memset( part_opstr, ' ', ident);
+              memset( part_opstr+ident, '\0', 1);
+              strncat( part_opstr, opstr+last_wrap_pos, wrap_pos-last_wrap_pos);                
+            }
+            
+            p.y += ascent;
+  
+            renderer_ops->draw_string(renderer,
+                                      part_opstr,
+                                      &p, ALIGN_LEFT, 
+                                      &umlclass->text_color);
+          
+            last_wrap_pos = wrap_pos;
+            wrapsublist = g_list_next( wrapsublist);
+          }
+        } else {
+
+          p.y += ascent;
+
         renderer_ops->draw_string(renderer,
                                    opstr,
                                    &p, ALIGN_LEFT, 
                                    &umlclass->text_color);
+        }
 
         if (op->class_scope) {
           p1 = p; 
@@ -787,7 +836,11 @@
 
   umlclass->operationsbox_height = 2*0.1;
 
+  int pos_next_comma, pos_brace, wrap_pos, last_wrap_pos, ident, offset, maxlinewidth, length;
+  GList *sublist, *wrapsublist;
+  
   umlclass->operations_strings = NULL;
+  umlclass->operations_wrappos = NULL;
   if (0 != g_list_length(umlclass->operations)) {
     i = 0;
     list = umlclass->operations;
@@ -798,6 +851,94 @@
       umlclass->operations_strings = 
         g_list_append(umlclass->operations_strings, opstr);
       
+      length = 0;
+      if( umlclass->wrap_operations == TRUE) {
+      
+        length = strlen( (const gchar*)opstr);
+        
+        sublist = NULL;
+        if( length > umlclass->wrap_after_char) {
+          
+          sublist = g_list_append( sublist, GINT_TO_POINTER( 1));
+          
+          /* count maximal line width to create a secure buffer (part_opstr)
+             and build the sublist with the wrapping data for the current operation, which will be used by umlclass_draw(), too. 
+             The content of the sublist is:
+             1st element: (bool) wrapping needed or not, 2nd: indentation in chars, 3rd-last: absolute wrapping positions */
+          pos_next_comma = pos_brace = wrap_pos = offset = maxlinewidth = umlclass->max_wrapped_line_width = 0;
+          while( wrap_pos + offset < length) {
+            
+            do {
+              pos_next_comma = strcspn( (const gchar*)opstr + wrap_pos + offset, ",");
+              wrap_pos += pos_next_comma + 1;
+            } 
+            while( wrap_pos < umlclass->wrap_after_char - pos_brace && wrap_pos + offset < length);
+            
+            if( offset == 0) {
+              pos_brace = strcspn( opstr, "(");
+              sublist = g_list_append( sublist, GINT_TO_POINTER( pos_brace+1));
+            }
+            sublist = g_list_append( sublist, GINT_TO_POINTER( wrap_pos + offset));
+            
+            maxlinewidth = MAX(maxlinewidth, wrap_pos);
+ 
+            offset += wrap_pos;
+            wrap_pos = 0;
+          }   
+          umlclass->max_wrapped_line_width = MAX( umlclass->max_wrapped_line_width, maxlinewidth+1);
+          
+          gchar part_opstr[umlclass->max_wrapped_line_width];
+          pos_next_comma = pos_brace = wrap_pos = offset = 0;
+          
+          wrapsublist = g_list_next( sublist);
+          ident = GPOINTER_TO_INT( wrapsublist->data);
+          wrapsublist = g_list_next( wrapsublist);
+          wrap_pos = last_wrap_pos = 0;
+          
+          while( wrapsublist != NULL) {
+            
+            wrap_pos = GPOINTER_TO_INT( wrapsublist->data);
+            
+            if( last_wrap_pos == 0) {
+              strncpy( part_opstr, opstr, wrap_pos);  
+              memset( part_opstr+wrap_pos, '\0', 1);
+            } else {  
+              memset( part_opstr, ' ', ident);
+              memset( part_opstr+ident, '\0', 1);
+              strncat( part_opstr, opstr+last_wrap_pos, wrap_pos-last_wrap_pos);                
+            }
+            
+            if (op->inheritance_type == UML_ABSTRACT) {
+              width = dia_font_string_width(part_opstr,
+                                            umlclass->abstract_font,
+                                            umlclass->abstract_font_height);
+              umlclass->operationsbox_height += umlclass->abstract_font_height;
+            } else if (op->inheritance_type == UML_POLYMORPHIC) {
+              width = dia_font_string_width(part_opstr,
+                                            umlclass->polymorphic_font,
+                                            umlclass->polymorphic_font_height);
+              umlclass->operationsbox_height += umlclass->polymorphic_font_height;        
+            } else {
+              width = dia_font_string_width(part_opstr,
+                                            umlclass->normal_font,
+                                            umlclass->font_height);
+              umlclass->operationsbox_height += umlclass->font_height;
+            }
+            
+            maxwidth = MAX(width, maxwidth);
+            last_wrap_pos = wrap_pos;
+            wrapsublist = g_list_next( wrapsublist);
+          }
+  
+        } else {
+          
+          sublist = g_list_append( sublist, GINT_TO_POINTER( 0));
+        }
+        umlclass->operations_wrappos = g_list_append( umlclass->operations_wrappos, sublist);
+      } 
+      
+      if( umlclass->wrap_operations == FALSE || !(length > umlclass->wrap_after_char)) {
+        
       if (op->inheritance_type == UML_ABSTRACT) {
         width = dia_font_string_width(opstr,
                                       umlclass->abstract_font,
@@ -814,8 +955,11 @@
                                       umlclass->font_height);
         umlclass->operationsbox_height += umlclass->font_height;
       }
+        
       maxwidth = MAX(width, maxwidth);
       
+      }
+                  
       if (umlclass->visible_comments && op->comment != NULL && op->comment[0] != '\0') {
         width = dia_font_string_width(op->comment,
                                       umlclass->comment_font,
@@ -953,6 +1097,9 @@
   umlclass->visible_operations = TRUE;
   umlclass->visible_comments = FALSE;
 
+  umlclass->wrap_operations = TRUE;
+  umlclass->wrap_after_char = UMLCLASS_WRAP_AFTER_CHAR;
+
   umlclass->attributes = NULL;
 
   umlclass->operations = NULL;
@@ -963,6 +1110,7 @@
   umlclass->stereotype_string = NULL;
   umlclass->attributes_strings = NULL;
   umlclass->operations_strings = NULL;
+  umlclass->operations_wrappos = NULL;
   umlclass->templates_strings = NULL;
   
   umlclass->text_color = color_black;
@@ -1059,6 +1207,12 @@
     umlclass->operations_strings = NULL;
   }
 
+  if (umlclass->operations_wrappos != NULL) {
+    g_list_foreach(umlclass->operations_wrappos, (GFunc)g_list_free, NULL);
+    g_list_free(umlclass->operations_wrappos);
+    umlclass->operations_wrappos = NULL;
+  }
+
   if (umlclass->templates_strings != NULL) {
     for (i=0;i<umlclass->num_templates;i++) {
       g_free(umlclass->templates_strings[i]);
@@ -1134,6 +1288,8 @@
   newumlclass->visible_attributes = umlclass->visible_attributes;
   newumlclass->visible_operations = umlclass->visible_operations;
   newumlclass->visible_comments = umlclass->visible_comments;
+  newumlclass->wrap_operations = umlclass->wrap_operations;
+  newumlclass->wrap_after_char = umlclass->wrap_after_char;
   newumlclass->text_color = umlclass->text_color;
   newumlclass->line_color = umlclass->line_color;
   newumlclass->fill_color = umlclass->fill_color;
@@ -1196,6 +1352,7 @@
   newumlclass->stereotype_string = NULL;
   newumlclass->attributes_strings = NULL;
   newumlclass->operations_strings = NULL;
+  newumlclass->operations_wrappos = NULL;
   newumlclass->templates_strings = NULL;
 
   for (i=0;i<UMLCLASS_CONNECTIONPOINTS;i++) {
@@ -1270,6 +1427,10 @@
 		   umlclass->visible_operations);
   data_add_boolean(new_attribute(obj_node, "visible_comments"),
 		   umlclass->visible_comments);
+  data_add_boolean(new_attribute(obj_node, "wrap_operations"),
+		   umlclass->wrap_operations);
+  data_add_int(new_attribute(obj_node, "wrap_after_char"),
+		   umlclass->wrap_after_char);
   data_add_color(new_attribute(obj_node, "line_color"), 
 		   &umlclass->line_color);
   data_add_color(new_attribute(obj_node, "fill_color"), 
@@ -1402,6 +1563,16 @@
   if (attr_node != NULL)
     umlclass->visible_comments = data_boolean(attribute_first_data(attr_node));
 
+  umlclass->wrap_operations = TRUE;
+  attr_node = object_find_attribute(obj_node, "wrap_operations");
+  if (attr_node != NULL)
+    umlclass->wrap_operations = data_boolean(attribute_first_data(attr_node));
+  
+  umlclass->wrap_after_char = UMLCLASS_WRAP_AFTER_CHAR;
+  attr_node = object_find_attribute(obj_node, "wrap_after_char");
+  if (attr_node != NULL)
+    umlclass->wrap_after_char = data_int(attribute_first_data(attr_node));
+
   umlclass->line_color = color_black;
   /* support the old name ... */
   attr_node = object_find_attribute(obj_node, "foreground_color");
@@ -1559,6 +1730,7 @@
   umlclass->stereotype_string = NULL;
   umlclass->attributes_strings = NULL;
   umlclass->operations_strings = NULL;
+  umlclass->operations_wrappos = NULL;
   umlclass->templates_strings = NULL;
 
   umlclass_calculate_data(umlclass);
diff -urNbB dia-0.93_orig/objects/UML/class.h dia-0.93/objects/UML/class.h
--- dia-0.93_orig/objects/UML/class.h	2004-02-29 21:55:14.000000000 +0100
+++ dia-0.93/objects/UML/class.h	2004-05-13 10:50:32.000000000 +0200
@@ -26,6 +26,7 @@
 #include "uml.h"
 
 #define UMLCLASS_CONNECTIONPOINTS 8
+#define UMLCLASS_WRAP_AFTER_CHAR 40
 
 typedef struct _UMLClass UMLClass;
 typedef struct _UMLClassDialog UMLClassDialog;
@@ -61,6 +62,9 @@
   int visible_operations;
   int visible_comments;
 
+  int wrap_operations; /* wrap operations with many parameters */
+  int wrap_after_char;
+
   Color line_color;
   Color fill_color;
   Color text_color;
@@ -85,6 +89,8 @@
   
   real operationsbox_height;
   GList *operations_strings;
+  GList **operations_wrappos;
+  int max_wrapped_line_width;
 
   real templates_height;
   real templates_width;
@@ -114,6 +120,7 @@
   GtkToggleButton *op_vis;
   GtkToggleButton *op_supp;
   GtkToggleButton *comments_vis;
+  GtkToggleButton *op_wrap;
   DiaFontSelector *normal_font;
   DiaFontSelector *abstract_font;
   DiaFontSelector *polymorphic_font;
@@ -126,9 +133,11 @@
   GtkSpinButton *classname_font_height;
   GtkSpinButton *abstract_classname_font_height;
   GtkSpinButton *comment_font_height;
+  GtkSpinButton *wrap_after_char;  
   DiaColorSelector *text_color;
   DiaColorSelector *line_color;
   DiaColorSelector *fill_color;
+  GtkLabel *max_length_label;
 
   GList *disconnected_connections;
   GList *added_connections; 
diff -urNbB dia-0.93_orig/objects/UML/class_dialog.c dia-0.93/objects/UML/class_dialog.c
--- dia-0.93_orig/objects/UML/class_dialog.c	2004-02-29 19:25:02.000000000 +0100
+++ dia-0.93/objects/UML/class_dialog.c	2004-05-13 11:50:59.000000000 +0200
@@ -149,6 +149,8 @@
   umlclass->abstract = prop_dialog->abstract_class->active;
   umlclass->visible_attributes = prop_dialog->attr_vis->active;
   umlclass->visible_operations = prop_dialog->op_vis->active;
+  umlclass->wrap_operations = prop_dialog->op_wrap->active;
+  umlclass->wrap_after_char = gtk_spin_button_get_value_as_int(prop_dialog->wrap_after_char);
   umlclass->visible_comments = prop_dialog->comments_vis->active;
   umlclass->suppress_attributes = prop_dialog->attr_supp->active;
   umlclass->suppress_operations = prop_dialog->op_supp->active;
@@ -193,6 +195,8 @@
   gtk_toggle_button_set_active(prop_dialog->abstract_class, umlclass->abstract);
   gtk_toggle_button_set_active(prop_dialog->attr_vis, umlclass->visible_attributes);
   gtk_toggle_button_set_active(prop_dialog->op_vis, umlclass->visible_operations);
+  gtk_toggle_button_set_active(prop_dialog->op_wrap, umlclass->wrap_operations);
+  gtk_spin_button_set_value (prop_dialog->wrap_after_char, umlclass->wrap_after_char);
   gtk_toggle_button_set_active(prop_dialog->comments_vis, umlclass->visible_comments);
   gtk_toggle_button_set_active(prop_dialog->attr_supp, umlclass->suppress_attributes);
   gtk_toggle_button_set_active(prop_dialog->op_supp, umlclass->suppress_operations);
@@ -245,6 +249,7 @@
   GtkWidget *page_label;
   GtkWidget *label;
   GtkWidget *hbox;
+  GtkWidget *hbox2;
   GtkWidget *vbox;
   GtkWidget *entry;
   GtkWidget *checkbox;
@@ -252,6 +257,7 @@
   GtkWidget *fill_color;
   GtkWidget *line_color;
   GtkWidget *table;
+  GtkObject *adj;
 
   prop_dialog = umlclass->properties_dialog;
 
@@ -310,6 +316,21 @@
   gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
 
+  hbox  = gtk_hbox_new(TRUE, 5);
+  hbox2 = gtk_hbox_new(FALSE, 5);
+  checkbox = gtk_check_button_new_with_label(_("Wrap Operations"));
+  prop_dialog->op_wrap = GTK_TOGGLE_BUTTON( checkbox );
+  gtk_box_pack_start (GTK_BOX (hbox), checkbox, TRUE, TRUE, 0);
+  adj = gtk_adjustment_new( umlclass->wrap_after_char, 0.0, 200.0, 1.0, 5.0, 1.0);
+  prop_dialog->wrap_after_char = GTK_SPIN_BUTTON(gtk_spin_button_new( GTK_ADJUSTMENT( adj), 0.1, 0));
+  gtk_spin_button_set_numeric( GTK_SPIN_BUTTON( prop_dialog->wrap_after_char), TRUE);
+  gtk_spin_button_set_snap_to_ticks( GTK_SPIN_BUTTON( prop_dialog->wrap_after_char), TRUE);
+  prop_dialog->max_length_label = GTK_LABEL( gtk_label_new( "Wrap after this length: "));
+  gtk_box_pack_start (GTK_BOX (hbox2), GTK_WIDGET( prop_dialog->max_length_label), FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox2), GTK_WIDGET( prop_dialog->wrap_after_char), TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET( hbox2), TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
   hbox = gtk_hbox_new(FALSE, 5);
   checkbox = gtk_check_button_new_with_label(_("Comments visible"));
   prop_dialog->comments_vis = GTK_TOGGLE_BUTTON( checkbox );


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] Mail converted by Mofo Magic and the Flying D

 
All trademarks and copyrights are the property of their respective owners.

Other Directory Sites: SeekWonder | Directory Owners Forum

GuideSMACK