Hello Dia-developers!

I implemented a patch for Dia yesterday against the Debian/Sarge dia package
source (attached in the mail). This patch implements a command-line option to
specify which layers to show on exports.

Today, I checked out the Dia CVS sources and found out that something very
similar was already implemented, --show-layers=NAME,NAME2,... Oops - I should
have started with CVS instead :-)

Anyway, my patch implements this slightly differently. In the patch, the
option is called --export-layers, and specifies a range of layers to
export. I.e.,

--export-layers=0-3   and  --export-layers=-3

Will export layers 0,1,2,3 (the lowermost layers)

--export-layers=2-4,7

will export layers 2,3,4,7

--export-layers=6-

will export layers from 6 and up.


I find this behaviour useful since I use the layer feature for slide
animations, where this fits well into Makefiles without overly long command
lines. Anyhow, would the rest of you be interested in YET another command line
option which does more or less the same thing as --show-layers? Maybe
--show-layers-range? If so, I could spend some time to rewrite the patch for
the CVS version (the patch doesn't apply to the CVS version, but it should be
possible to see how it works).

If not - at least I've learned to always look at the latest source first ;-)

// Simon
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
_______________________________________________
Dia-list mailing list
[email protected]
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

Reply via email to