Package: dia
Version: 0.94.0-7
Severity: wishlist

I think it would be good to be able to specify which layers to export,
e.g., with something like --export-layers=0-2,5 for showing only the
layers 0,1,2,5 in the exported file. I implemented this in a patch
against the dia in Debian Sarge, which is attached here.

I find this feature useful using Dia for creating "animated" figures for
slides, in which case something like this is good for integrating it in
Makefiles.

I dont know if I should have sent it to the upstream authors directly,
but here it goes :-)

Thanks,
// Simon

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.4.27-1-686
Locale: LANG=C, LC_CTYPE=sv_SE (charmap=ISO-8859-1)

Versions of packages dia depends on:
ii  dia-common                  0.94.0-7     Diagram editor (common files)
ii  dia-libs                    0.94.0-7     Diagram editor (library files)
ii  libart-2.0-2                2.3.17-1     Library of functions for 2D graphi
ii  libatk1.0-0                 1.8.0-4      The ATK accessibility toolkit
ii  libc6                       2.3.2.ds1-20 GNU C Library: Shared libraries an
ii  libfreetype6                2.1.7-2.3    FreeType 2 font engine, shared lib
ii  libglib2.0-0                2.6.3-1      The GLib library of C routines
ii  libgtk2.0-0                 2.6.2-4      The GTK+ graphical user interface 
ii  libpango1.0-0               1.8.1-1      Layout and rendering of internatio
ii  libpng12-0                  1.2.8rel-1   PNG library - runtime
ii  libpopt0                    1.7-5        lib for parsing cmdline parameters
ii  libxml2                     2.6.16-4     GNOME XML library
ii  zlib1g                      1:1.2.2-3    compression library - runtime

-- no debconf information
diff -ru dia-0.94.0/app/app_procs.c /home/ska/projects/private/dia/dia-0.94.0/app/app_procs.c
--- dia-0.94.0/app/app_procs.c	2005-04-02 21:00:28.000000000 +0200
+++ /home/ska/projects/private/dia/dia-0.94.0/app/app_procs.c	2005-04-02 21:38:12.000000000 +0200
@@ -100,7 +100,8 @@
 handle_initial_diagram(const char *input_file_name, 
 		       const char *export_file_name,
 		       const char *export_file_format,
-		       const char *size);
+		       const char *size,
+		       const char *export_layer);
 
 static void create_user_dirs(void);
 static PluginInitResult internal_plugin_init(PluginInfo *info);
@@ -109,9 +110,11 @@
 			 poptContext poptCtx, struct poptOption options[],
 #endif
 			 GSList **files, char **export_file_name,
-			 char **export_file_format, char **size);
+			 char **export_file_format, char **size,
+			 char **export_layers);
 static gboolean handle_all_diagrams(GSList *files, char *export_file_name,
-				    char *export_file_format, char *size);
+				    char *export_file_format, char *size,
+				    char *export_layers);
 static void print_credits(gboolean credits);
 
 static gboolean dia_is_interactive = TRUE;
@@ -201,6 +204,119 @@
 
 const char *argv0 = NULL;
 
+
+/* Handle the string between commas. We have either of:
+ *
+ * 1. XX, the number XX
+ * 2. -XX, every number until XX
+ * 3. XX-, every number from XX until n_layers
+ * 4. XX-YY, every number between XX-YY
+ */
+static void
+layer_visibility_handle_substr(gboolean *visible_layers, gint n_layers, const char *str)
+{
+  char *p = str;
+  unsigned long int low = 0;
+  unsigned long int high = n_layers;
+  unsigned long int i;
+
+  if (str == NULL)
+    return;
+
+  /* Case 2, starts with '-' */
+  if (*str == '-') {
+    str++;
+    low = 0;
+    high = strtoul(str, &p, 10)+1;
+    if (p == str) {
+      g_error(_("error: Cannot convert %s into a number\n"), str );
+      exit(1);
+    }
+  }
+  else {
+    /* Case 1, 3 or 4 */
+    low = strtoul(str, &p, 10);
+    high = low+1; /* Assume case 1 */
+    if (p == str) {
+      g_error(_("error: Cannot convert %s into a number\n"), str );
+      exit(1);
+    }
+    if (*p == '-')
+      {
+	/* Case 3 or 4 */
+	str = p + 1;
+	if (*str == '\0') /* Case 3 */
+	  high = n_layers;
+	else
+	  {
+	    high = strtoul(str, &p, 10)+1;
+	    if (p == str) {
+	      g_error(_("error: Cannot convert %s into a number\n"), str );
+	      exit(1);
+	    }
+	  }
+      }
+  }
+
+  if ( high <= low ) {
+    g_error(_("error: invalid layer range %lu - %lu\n"), low, high-1 );
+    exit(1);
+  }
+  if (high > n_layers)
+    high = n_layers;
+
+  /* Set the visible layers */
+  for ( i = low; i < high; i++ )
+    visible_layers[i] = TRUE;
+}
+
+static void
+layer_visibility_parse_string(gboolean *visible_layers, gint n_layers, const char *str)
+{
+  char *p, *dummy;
+  char *cpy = strdup(str);
+
+  if (!cpy) {
+    g_error(_("error: strdup failed\n") );
+    exit(1);
+  }
+
+  for (p = strtok_r(cpy, ",", &dummy);
+       p != NULL;
+       p = strtok_r(NULL, ",", &dummy)) {
+    layer_visibility_handle_substr(visible_layers, n_layers, p);
+  }
+
+  free(cpy);
+}
+
+
+static void
+handle_layer_visibility(DiagramData *diagdata, const char *layer_visibility_string)
+{
+  gboolean *visible_layers;
+  Layer *layer;
+  int i;
+
+  visible_layers = g_malloc(diagdata->layers->len * sizeof(gboolean));
+  /* Assume all layers are non-visible */
+  for (i=0;i<diagdata->layers->len;i++)
+    visible_layers[i] = FALSE;
+
+  layer_visibility_parse_string(visible_layers, diagdata->layers->len,
+				layer_visibility_string);
+
+  for (i=0;i<diagdata->layers->len;i++) {
+    layer = g_ptr_array_index(diagdata->layers, i);
+
+    if (visible_layers[i] == TRUE)
+      layer->visible = TRUE;
+    else
+      layer->visible = FALSE;
+  }
+  g_free(visible_layers);
+}
+
 /** Convert infname to outfname, using input filter inf and export filter
  * ef.  If either is null, try to guess them.
  * size might be NULL.
@@ -208,7 +324,8 @@
 gboolean
 do_convert(const char *infname, 
 	   const char *outfname, DiaExportFilter *ef,
-	   const char *size)
+	   const char *size,
+	   const char *export_layers)
 {
   DiaImportFilter *inf;
   DiagramData *diagdata = NULL;
@@ -240,6 +357,9 @@
             argv0, infname);
     exit(1);
   }
+  if (export_layers != NULL)
+    handle_layer_visibility(diagdata, export_layers);
+
   /* Do our best in providing the size to the filter, but don't abuse user_data 
    * too much for it. It _must not_ be changed after initialization and there 
    * are quite some filter selecting their output format by it. --hb
@@ -287,7 +407,8 @@
 handle_initial_diagram(const char *in_file_name, 
 		       const char *out_file_name,
 		       const char *export_file_format,
-		       const char *size) {
+		       const char *size,
+		       const char *export_layers) {
   DDisplay *ddisp = NULL;
   Diagram *diagram = NULL;
   gboolean made_conversions = FALSE;
@@ -316,7 +437,8 @@
 						ef->extensions[0]);
     }
     made_conversions |= do_convert(in_file_name,
-      (out_file_name != NULL?out_file_name:export_file_name), ef, size);
+      (out_file_name != NULL?out_file_name:export_file_name), ef, size,
+				   export_layers);
     g_free(export_file_name);
   } else if (out_file_name) {
     DiaExportFilter *ef = NULL;
@@ -326,7 +448,7 @@
       ef = filter_get_by_name ("png-libart");
     
     made_conversions |= do_convert(in_file_name, out_file_name, ef,
-				   size);
+				   size, export_layers);
   } else {
     if (g_file_test(in_file_name, G_FILE_TEST_EXISTS)) {
       diagram = diagram_load (in_file_name, NULL);
@@ -395,6 +517,7 @@
   char *export_file_name = NULL;
   char *export_file_format = NULL;
   char *size = NULL;
+  char *export_layers = NULL;
   gboolean made_conversions = FALSE;
   GSList *files = NULL;
 
@@ -415,6 +538,8 @@
     {"export-to-format",'t', POPT_ARG_STRING, NULL /* &export_file_format */,
      0, export_format_string, N_("FORMAT")
     },
+    {"export-layers",'x', POPT_ARG_STRING, NULL /* &export_layers */, 0,
+     N_("Select which layers to export"), N_("LAYERS")},
     {"size", 's', POPT_ARG_STRING, NULL, 0,
      N_("Export graphics size"), N_("WxH")},
     {"nosplash", 'n', POPT_ARG_NONE, &nosplash, 0,
@@ -433,7 +558,8 @@
 #ifdef HAVE_POPT
   options[0].arg = &export_file_name;
   options[1].arg = &export_file_format;
-  options[2].arg = &size;
+  options[2].arg = &export_layers;
+  options[3].arg = &size;
 #endif
 
   argv0 = (argc > 0) ? argv[0] : "(none)";
@@ -449,7 +575,8 @@
                poptCtx, options, 
 #endif
                &files,
-	     &export_file_name, &export_file_format, &size);
+	     &export_file_name, &export_file_format, &size,
+	     &export_layers);
 
 #if defined ENABLE_NLS && defined HAVE_BIND_TEXTDOMAIN_CODESET
   bind_textdomain_codeset(GETTEXT_PACKAGE,"UTF-8");  
@@ -591,7 +718,8 @@
   }
 
   made_conversions = handle_all_diagrams(files, export_file_name,
-					 export_file_format, size);
+					 export_file_format, size,
+					 export_layers);
   if (dia_is_interactive && files == NULL) {
     gchar *filename = g_filename_from_utf8(_("Diagram1.dia"), -1, NULL, NULL, NULL);
     Diagram *diagram = new_diagram (filename);
@@ -784,7 +912,8 @@
 	     poptContext poptCtx, struct poptOption options[],
 #endif
 	     GSList **files, char **export_file_name,
-	     char **export_file_format, char **size)
+	     char **export_file_format, char **size,
+	     char **export_layers)
 {
 #ifdef HAVE_POPT
   int rc = 0;
@@ -836,6 +965,12 @@
                   *size = argv[i];
                   continue;
               }
+          } else if (0 == strcmp(argv[i],"-x")) {
+              if (i < (argc-1)) {
+                  i++;
+                  *export_layers = argv[i];
+                  continue;
+              }
           }
 	  *files = g_slist_append(*files, in_file_name);
       }
@@ -847,7 +982,8 @@
 
 static gboolean
 handle_all_diagrams(GSList *files, char *export_file_name,
-		    char *export_file_format, char *size)
+		    char *export_file_format, char *size,
+		    char *export_layers)
 {
   GSList *node = NULL;
   gboolean made_conversions = FALSE;
@@ -855,7 +991,7 @@
   for (node = files; node; node = node->next) {
     made_conversions |=
       handle_initial_diagram(node->data, export_file_name,
-			     export_file_format, size);
+			     export_file_format, size, export_layers);
   }
   return made_conversions;
 }
diff -ru dia-0.94.0/app/app_procs.h /home/ska/projects/private/dia/dia-0.94.0/app/app_procs.h
--- dia-0.94.0/app/app_procs.h	2004-08-16 09:56:03.000000000 +0200
+++ /home/ska/projects/private/dia/dia-0.94.0/app/app_procs.h	2005-04-02 20:37:11.000000000 +0200
@@ -30,7 +30,8 @@
 
 gboolean do_convert(const char *infname,
 		    const char *outfname, DiaExportFilter *ef,
-		    const char *size);
+		    const char *size,
+		    const char *export_layers);
 char *build_output_file_name(const char *infname, const char *format);
 
 void app_splash_init(const gchar* name);
Only in /home/ska/projects/private/dia/dia-0.94.0/app: tst.eps
Only in /home/ska/projects/private/dia/dia-0.94.0/: conf1526.file
diff -ru dia-0.94.0/debian/dia.1 /home/ska/projects/private/dia/dia-0.94.0/debian/dia.1
--- dia-0.94.0/debian/dia.1	2005-04-02 21:00:28.000000000 +0200
+++ /home/ska/projects/private/dia/dia-0.94.0/debian/dia.1	2005-04-02 21:56:40.000000000 +0200
@@ -25,8 +25,8 @@
 .nf
 \fBdia\fR [\fB-c\fR] [\fB--credits\fR] [\fB-e \fIOUTPUT\fR\fR] [\fB--export=\fIOUTPUT\fR\fR]
     [\fB-h\fR] [\fB--help\fR] [\fB-n\fR] [\fB--nosplash\fR] [\fB-t \fIFORMAT\fR\fR]
-    [\fB--export-to-format=\fIFORMAT\fR\fR] [\fB-v\fR] [\fB--version\fR] [file
-    \&.\&.\&.]
+    [\fB--export-to-format=\fIFORMAT\fR\fR] [\fB--export-layers=\fILAYERS\fR\fR]
+    [\fB-v\fR] [\fB--version\fR] [file\&.\&.\&.]
 .fi
 
 .SH "DESCRIPTION"
@@ -66,6 +66,10 @@
 Export loaded file in FORMAT and exit\&. Format are described below\&.
 
 .TP
+\fB-x \fILAYERS\fR\fR \fB--export-layers=\fILAYERS\fR\fR
+Only export the LAYERS layers\&. Use with \fB--export\fR\&.
+
+.TP
 \fB-s \fIWIDTHxHEIGHT\fR\fR \fB--size=\fIWIDTHxHEIGHT\fR\fR
 Size for exported bitmap graphics\&.
 
@@ -121,6 +125,24 @@
 wmf (Windows MetaFile)
 .LP
 
+.SH "SPECIFYING LAYERS"
+
+With the \fB--export-layers\fR option, the layers to show is specified as a
+comma-delimited list of layer numbers. Adjacent layers can be specified as
+\fIXX-YY\fR, i.e., all layers from \fIXX\fR to \fIYY\fR will be
+included. \fIXX-\R will export all layers from \fIXX\fR until the last layer
+and \fI-XX\R will export all layers from the first to \fIXX\fR.
+
+Examples:
+
+\fB--export-layers 0-4\fR Export layers \fI0-4\fR.
+
+\fB--export-layers 1\fR Export only layer \fI1\fR.
+
+\fB--export-layers 0-2,3,5-7\fR Export layer \fI0-2\fR, \fI3\fR and \fI5-7\fR.
+
+\fB--export-layers -5\fR Export layers \fI0-5\fR.
+
 .SH "FILES"
 
 .PP

Reply via email to