Beispiel #1
0
static void
_dae_draw(DiagramAsElement *dae, DiaRenderer *renderer)
{
  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
  Element *elem = &dae->element;

  if (!dae->data) {
    /* just draw the box */
    Point lower_right = {
      elem->corner.x + elem->width,
      elem->corner.y + elem->height 
    };

    renderer_ops->draw_rect(renderer,&elem->corner, &lower_right, 
                            &dae->border_color);

  } else {
    if (FALSE) {
      /* if the renderer supports transformations ... */
      /* temporary messing with it (not enough) */
      dae->data->paper.scaling *= dae->scale;
      data_render (dae->data, DIA_RENDERER (renderer), NULL, NULL, NULL);
      dae->data->paper.scaling /= dae->scale;
    } else {
      /* we have to render to an image and draw that */
      if (!dae->image) { /* lazy creation */
	gchar *imgfname = NULL;
	gint fd = g_file_open_tmp ("diagram-as-elementXXXXXX.png", &imgfname, NULL);
	if (fd != -1) {
          DiaExportFilter *ef = filter_export_get_by_name ("cairo-alpha-png");
	  if (!ef) /* prefer cairo with alpha, but don't require it */
	    ef = filter_guess_export_filter (imgfname);
	  close(fd);
	  if (ef) {
	    DiaContext *ctx = dia_context_new ("Diagram as Object");

	    dia_context_set_filename (ctx, imgfname);
	    if (ef->export_func (dae->data, ctx, imgfname, dae->filename, ef->user_data)) {
	      DiaImage *tmp_image = dia_image_load (imgfname);

	      /* some extra gymnastics to create an image w/o filename */
	      if (tmp_image) {
	        dae->image = dia_image_new_from_pixbuf ((GdkPixbuf *)dia_image_pixbuf (tmp_image));
	        g_object_unref (tmp_image);
	      }
	      /* FIXME: where to put the message in case of an error? */
	      dia_context_release (ctx);
	    }
	  } /* found a filter */
	  g_unlink (imgfname);
	  g_free (imgfname);
	} /* temporary file created*/
      } /* only if we have no image yet */
      if (dae->image)
	renderer_ops->draw_image (renderer, &elem->corner, elem->width, elem->height, dae->image);
    }
  }
}
Beispiel #2
0
/*! Allows to save an Object to ObjectNode file filename.
 * . Not sure if this becomes useful for language bindings.
 */
void 
dia::ObjectType::save (Object* o, ObjectNode node, const char* filename) const
{
    assert (self);
    DiaContext *ctx = dia_context_new ("Object save");
    self->ops->save (o->Self(), node, ctx);
    dia_context_reset (ctx);
    dia_context_release (ctx);
}
Beispiel #3
0
static void
_dae_update_data(DiagramAsElement *dae)
{
  struct stat statbuf;
  Element *elem = &dae->element;
  DiaObject *obj = &elem->object;
  static int working = 0;
  
  if (working > 2)
    return; /* protect against infinite recursion */
  ++working;

  if (   strlen(dae->filename)
      && g_stat(dae->filename, &statbuf) == 0
      && dae->mtime != statbuf.st_mtime) {
    DiaImportFilter *inf;

    if (dae->data)
      g_object_unref(dae->data);
    dae->data = g_object_new (DIA_TYPE_DIAGRAM_DATA, NULL);

    inf = filter_guess_import_filter(dae->filename);
    if (inf) {
      DiaContext *ctx = dia_context_new (diagram_as_element_type.name);

      dia_context_set_filename (ctx, dae->filename);
      if (inf->import_func(dae->filename, dae->data, ctx, inf->user_data)) {
        data_update_extents (dae->data); /* should already be called by importer? */
        dae->scale = dae->element.width / (dae->data->extents.right - dae->data->extents.left);
        dae->element.height = (dae->data->extents.bottom - dae->data->extents.top) * dae->scale;
        dae->mtime = statbuf.st_mtime;
      }
      /* FIXME: where to put the message in case of an error? */
      dia_context_release (ctx);
    }
    /* invalidate possibly cached image */
    if (dae->image) {
      g_object_unref (dae->image);
      dae->image = NULL;
    }
  }
  /* fixme - fit the scale to draw the diagram in elements size ?*/
  if (dae->scale)
    dae->scale = dae->element.width / (dae->data->extents.right - dae->data->extents.left);

  elem->extra_spacing.border_trans = dae->border_line_width/2.0;
  element_update_boundingbox(elem);
  element_update_handles(elem);
  element_update_connections_rectangle(elem, dae->connections);

  /* adjust objects position, otherwise it'll jump on move */
  obj->position = elem->corner;

  --working;
}
Beispiel #4
0
int
diagram_load_into(Diagram         *diagram,
		  const char      *filename,
		  DiaImportFilter *ifilter)
{
  /* ToDo: move context further up in the callstack and to sth useful with it's content */
  DiaContext *ctx = dia_context_new(_("Load Into"));

  gboolean was_default = diagram->is_default;
  if (!ifilter)
    ifilter = filter_guess_import_filter(filename);
  /* slightly hacked to avoid 'Not a Dia File' for .shape */
  if (!ifilter && g_str_has_suffix (filename, ".shape"))
    ifilter = filter_import_get_by_name ("dia-svg");
  if (!ifilter)  /* default to native format */
    ifilter = &dia_import_filter;

  dia_context_set_filename (ctx, filename);
  if (ifilter->import_func(filename, diagram->data, ctx, ifilter->user_data)) {
    if (ifilter != &dia_import_filter) {
      /* When loading non-Dia files, change filename to reflect that saving
       * will produce a Dia file. See bug #440093 */
      if (strcmp (diagram->filename, filename) == 0) {
	/* not a real load into but initial load */
	gchar *old_filename = g_strdup (diagram->filename);
        gchar *suffix_offset = g_utf8_strrchr(old_filename, -1, (gunichar)'.');
        gchar *new_filename;
        if (suffix_offset != NULL) {
	  new_filename = g_strndup(old_filename, suffix_offset - old_filename);
	  g_free(old_filename);
	} else {
	  new_filename = old_filename;
	}
        old_filename = g_strconcat(new_filename, ".dia", NULL);
        g_free(new_filename);
        diagram_set_filename(diagram, old_filename);
        g_free(old_filename);
        diagram->unsaved = TRUE;
	diagram_update_for_filename (diagram);
	diagram_modified(diagram);
      }
    } else {
      /* the initial diagram should have confirmed filename  */
      diagram->unsaved = 
	  strcmp(filename, diagram->filename) == 0 ? FALSE : was_default;
    }
    diagram_set_modified(diagram, TRUE);
    dia_context_release(ctx);
    return TRUE;
  } else {
    dia_context_release(ctx);
    return FALSE;
  }
}
Beispiel #5
0
static void
are_you_sure_close_dialog_respond(GtkWidget *widget, /* the dialog */
                                  gint       response_id,
                                  gpointer   user_data) /* the display */
{
  DDisplay *ddisp = (DDisplay *)user_data;
  gboolean close_ddisp = TRUE;

  switch (response_id) {
  case GTK_RESPONSE_YES :  
    /* save changes */
    if (ddisp->diagram->unsaved) {
      /* we have to open the file dlg, close this one first */
      gtk_widget_destroy(widget);
      if (file_save_as(ddisp->diagram, ddisp))
        ddisp_destroy (ddisp);
      /* no way back */
      return;
    } else {
      DiaContext *ctx = dia_context_new (_("Save"));
      if (!diagram_save(ddisp->diagram, ddisp->diagram->filename, ctx))
        close_ddisp = FALSE;
      dia_context_release (ctx);
    }
    if (close_ddisp) /* saving succeeded */
      recent_file_history_add(ddisp->diagram->filename);

    if (ddisp->update_id && close_ddisp) {
      g_source_remove (ddisp->update_id);
      ddisp->update_id = 0;
    }
    /* fall through */
  case GTK_RESPONSE_NO :
    if (close_ddisp)
      ddisp_destroy (ddisp);
    /* fall through */
  case GTK_RESPONSE_CANCEL :
  case GTK_RESPONSE_NONE :
  case GTK_RESPONSE_DELETE_EVENT : /* closing via window manager */
    gtk_widget_destroy(widget);
    break;
  default :
    g_assert_not_reached();
  }
}
Beispiel #6
0
void
app_init (int argc, char **argv)
{
  static gboolean nosplash = FALSE;
  static gboolean nonew = FALSE;
  static gboolean use_integrated_ui = TRUE;
  static gboolean credits = FALSE;
  static gboolean version = FALSE;
  static gboolean verbose = FALSE;
  static gboolean log_to_stderr = FALSE;
#ifdef HAVE_GNOME
  GnomeClient *client;
#endif
  static char *export_file_name = NULL;
  static char *export_file_format = NULL;
  static char *size = NULL;
  static char *show_layers = NULL;
  gboolean made_conversions = FALSE;
  GSList *files = NULL;
  static const gchar **filenames = NULL;
  int i = 0;

  gchar *export_format_string = 
     /* Translators:  The argument is a list of options, not to be translated */
    g_strdup_printf(_("Select the filter/format out of: %s"),
		    "cgm, dia, dxf, eps, eps-builtin, " EPS_PANGO
		    "fig, mp, plt, hpgl, png ("
#  if defined(HAVE_LIBPNG) && defined(HAVE_LIBART)
		    "png-libart, "
#  endif
#  ifdef HAVE_CAIRO
		    "cairo-png, cairo-alpha-png, "
#  endif
		    /* we always have pixbuf but don't know exactly all it's *few* save formats */
		    "pixbuf-png), jpg, "
		    "shape, svg, tex (pgf-tex, pstricks-tex), " WMF
		    "wpg");

  GOptionContext *context = NULL;
  static GOptionEntry options[] =
  {
    {"export", 'e', 0, G_OPTION_ARG_FILENAME, NULL /* &export_file_name */,
     N_("Export loaded file and exit"), N_("OUTPUT")},
    {"filter",'t', 0, G_OPTION_ARG_STRING, NULL /* &export_file_format */,
     NULL /* &export_format_string */, N_("TYPE") },
    {"size", 's', 0, G_OPTION_ARG_STRING, NULL,
     N_("Export graphics size"), N_("WxH")},
    {"show-layers", 'L', 0, G_OPTION_ARG_STRING, NULL,
     N_("Show only specified layers (e.g. when exporting). Can be either the layer name or a range of layer numbers (X-Y)"),
     N_("LAYER,LAYER,...")},
    {"nosplash", 'n', 0, G_OPTION_ARG_NONE, &nosplash,
     N_("Don't show the splash screen"), NULL },
    {"nonew", 'n', 0, G_OPTION_ARG_NONE, &nonew,
     N_("Don't create an empty diagram"), NULL },
    {"classic", '\0', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &use_integrated_ui,
     N_("Start classic user interface (no diagrams in tabs)"), NULL },
    {"log-to-stderr", 'l', 0, G_OPTION_ARG_NONE, &log_to_stderr,
     N_("Send error messages to stderr instead of showing dialogs."), NULL },
    {"input-directory", 'I', 0, G_OPTION_ARG_CALLBACK, _check_option_input_directory,
     N_("Directory containing input files"), N_("DIRECTORY")},
    {"output-directory", 'O', 0, G_OPTION_ARG_CALLBACK, _check_option_output_directory,
     N_("Directory containing output files"), N_("DIRECTORY")},
    {"credits", 'c', 0, G_OPTION_ARG_NONE, &credits,
     N_("Display credits list and exit"), NULL },
    {"verbose", 0, 0, G_OPTION_ARG_NONE, &verbose,
     N_("Generate verbose output"), NULL },
    {"version", 'v', 0, G_OPTION_ARG_NONE, &version,
     N_("Display version and exit"), NULL },
    { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, NULL /* &filenames */,
      NULL, NULL },
    { NULL }
  };
  
  /* for users of app_init() the default is interactive */
  dia_is_interactive = TRUE;

  options[0].arg_data = &export_file_name;
  options[1].arg_data = &export_file_format;
  options[1].description = export_format_string;
  options[2].arg_data = &size;
  options[3].arg_data = &show_layers;
  g_assert (strcmp (options[13].long_name, G_OPTION_REMAINING) == 0);
  options[13].arg_data = (void*)&filenames;

  argv0 = (argc > 0) ? argv[0] : "(none)";

#if GTK_CHECK_VERSION(2,24,0)
  /* ... use setlocale directly? */
#else
  gtk_set_locale();
#endif
  setlocale(LC_NUMERIC, "C");
  _setup_textdomains ();

  context = g_option_context_new(_("[FILE...]"));
  g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
#ifndef HAVE_GNOME
  /* avoid to add it a second time */
  g_option_context_add_group (context, gtk_get_option_group (FALSE));
#endif
  if (argv) {
    GError *error = NULL;

    if (!g_option_context_parse (context, &argc, &argv, &error)) {
      if (error) { /* IMO !error here is a bug upstream, triggered e.g. with --gdk-debug=updates */
	g_print ("%s", error->message);
	g_error_free (error);
      } else {
	g_print (_("Invalid option?"));
      }

      g_option_context_free(context);
      exit(1);
    }
    /* second level check of command line options, existance of input files etc. */
    if (filenames) {
      while (filenames[i] != NULL) {
	gchar *filename; 
	gchar *testpath;	  

	if (g_str_has_prefix (filenames[i], "file://")) {
	  filename = g_filename_from_uri (filenames[i], NULL, NULL);
	  if (!g_utf8_validate(filename, -1, NULL)) {
	    gchar *tfn = filename;
	    filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
	    g_free(tfn);
	  }
	} else
	  filename = g_filename_to_utf8 (filenames[i], -1, NULL, NULL, NULL);

	if (!filename) {
	  g_print (_("Filename conversion failed: %s\n"), filenames[i]);
	  continue;
	}

	if (g_path_is_absolute(filename))
	  testpath = filename;
	else
	  testpath = g_build_filename(input_directory ? input_directory : ".", filename, NULL);

	/* we still have a problem here, if GLib's file name encoding would not be utf-8 */
	if (g_file_test (testpath, G_FILE_TEST_IS_REGULAR))
	  files = g_slist_append(files, filename);
	else {
	  g_print (_("Missing input: %s\n"), filename);
	  g_free (filename);
	}
	if (filename != testpath)
	  g_free (testpath);
	++i;
      }
    }
    /* given some files to output, we are not starting up the UI */
    if (export_file_name || export_file_format || size)
      dia_is_interactive = FALSE;

  }

  if (argv && dia_is_interactive && !version) {
#ifdef HAVE_GNOME
    GnomeProgram *program =
      gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,
			  argc, argv,
			  /* haven't found a quick way to pass GOption here */
			  GNOME_PARAM_GOPTION_CONTEXT, context,
			  GNOME_PROGRAM_STANDARD_PROPERTIES,
			  GNOME_PARAM_NONE);
    client = gnome_master_client();
    if(client == NULL) {
      g_warning(_("Can't connect to session manager!\n"));
    }
    else {
      g_signal_connect(G_OBJECT (client), "save_yourself",
		       G_CALLBACK (save_state), NULL);
      g_signal_connect(G_OBJECT (client), "die",
		       G_CALLBACK (session_die), NULL);
    }

    /* This smaller icon is 48x48, standard Gnome size */
    /* gnome_window_icon_set_default_from_file (GNOME_ICONDIR"/dia_gnome_icon.png");*/

#else
#  ifdef G_THREADS_ENABLED
    g_thread_init (NULL);
#  endif
    gtk_init(&argc, &argv);
#endif
  }
  else {
#ifdef G_THREADS_ENABLED
    g_thread_init (NULL);
#endif
    g_type_init();
    /*
     * On Windows there is no command line without display so that gtk_init is harmless. 
     * On X11 we need gtk_init_check() to avoid exit() just because there is no display 
     * running outside of X11.
     */
    if (!gtk_init_check(&argc, &argv))
      dia_log_message ("Running without display");
  }

  /* done with option parsing, don't leak */
  g_free(export_format_string);
  
  if (version) {
    gchar *ver_utf8;
    gchar *ver_locale;
#if (defined __TIME__) && (defined __DATE__)
    /* TRANSLATOR: 2nd and 3rd %s are time and date respectively. */
    ver_utf8 = g_strdup_printf(_("Dia version %s, compiled %s %s\n"), VERSION, __TIME__, __DATE__);
#else
    ver_utf8 = g_strdup_printf(_("Dia version %s\n"), VERSION);
#endif
    ver_locale = g_locale_from_utf8(ver_utf8, -1, NULL, NULL, NULL);
    printf("%s\n", ver_locale);
    g_free(ver_locale);
    g_free(ver_utf8);
    if (verbose)
      dump_dependencies();
    exit(0);
  }

  if (!dia_is_interactive)
    log_to_stderr = TRUE;

  libdia_init (   (dia_is_interactive ? DIA_INTERACTIVE : 0)
	       | (log_to_stderr ? DIA_MESSAGE_STDERR : 0)
	       | (verbose ? DIA_VERBOSE : 0) );

  print_credits(credits);

  if (dia_is_interactive) {
    create_user_dirs();

    if (!nosplash)
      app_splash_init("");

    /* Init cursors: */
    default_cursor = gdk_cursor_new(GDK_LEFT_PTR);
    ddisplay_set_all_cursor(default_cursor);
  }

  dia_register_plugins();
  dia_register_builtin_plugin(internal_plugin_init);

  load_all_sheets();     /* new mechanism */

  dia_log_message ("object defaults");
  {
    DiaContext *ctx = dia_context_new (_("Object Defaults"));
    dia_object_defaults_load (NULL, TRUE /* prefs.object_defaults_create_lazy */, ctx);
    dia_context_release (ctx);
  }
  debug_break();

  if (object_get_type("Standard - Box") == NULL) {
    message_error(_("Couldn't find standard objects when looking for "
		  "object-libs; exiting...\n"));
    g_critical( _("Couldn't find standard objects when looking for "
	    "object-libs in '%s'; exiting...\n"), dia_get_lib_directory("dia"));
    exit(1);
  }

  persistence_load();

  /** Must load prefs after persistence */
  prefs_init();

  if (dia_is_interactive) {

    /* further initialization *before* reading files */  
    active_tool = create_modify_tool();

    dia_log_message ("ui creation");
    if (use_integrated_ui) {
      create_integrated_ui();
    } else {
      create_toolbox();
      /* for the integrated ui case it is integrated */
      persistence_register_window_create("layer_window",
				         (NullaryFunc*)&layer_dialog_create);
    }
      
    /*fill recent file menu */
    recent_file_history_init();

    /* Set up autosave to check every 5 minutes */
    g_timeout_add_seconds(5*60, autosave_check_autosave, NULL);

#if 0 /* do we really open these automatically in the next session? */
    persistence_register_window_create("diagram_tree", 
                                       &diagram_tree_show);
#endif
    persistence_register_window_create("sheets_main_dialog",
				       (NullaryFunc*)&sheets_dialog_create);

    /* In current setup, we can't find the autosaved files. */
    /*autosave_restore_documents();*/

  }

  dia_log_message ("diagrams");
  made_conversions = handle_all_diagrams(files, export_file_name,
					 export_file_format, size, show_layers,
					 input_directory, output_directory);
					 
  if (dia_is_interactive && files == NULL && !nonew) {
    if (use_integrated_ui) {
      GList * list;
    
      file_new_callback(NULL);  
      list = dia_open_diagrams();
      if (list) {
        Diagram * diagram = list->data;
        diagram_update_extents(diagram);
        diagram->is_default = TRUE;
      }
    } else {
      gchar *filename = g_filename_from_utf8(_("Diagram1.dia"), -1, NULL, NULL, NULL);
      Diagram *diagram = new_diagram (filename);
      g_free(filename);
    
      if (diagram != NULL) {
        diagram_update_extents(diagram);
        diagram->is_default = TRUE;
        /* I think this is done in diagram_init() with a call to 
         * layer_dialog_update_diagram_list() */
        layer_dialog_set_diagram(diagram);
        new_display(diagram); 
      }
    }
  }
  g_slist_free(files);
  if (made_conversions) exit(0);

  dynobj_refresh_init();
  dia_log_message ("initialized");
}
Beispiel #7
0
/** Convert infname to outfname, using input filter inf and export filter
 * ef.  If either is null, try to guess them.
 * size might be NULL.
 */
static gboolean
do_convert(const char *infname, 
	   const char *outfname, DiaExportFilter *ef,
	   const char *size,
	   char *show_layers)
{
  DiaImportFilter *inf;
  DiagramData *diagdata = NULL;
  DiaContext *ctx;

  inf = filter_guess_import_filter(infname);
  if (!inf) 
    inf = &dia_import_filter;

  if (ef == NULL) {
    ef = filter_guess_export_filter(outfname);
    if (!ef) {
      g_critical(_("%s error: don't know how to export into %s\n"),
	      argv0,outfname);
      exit(1);
    }
  }

  dia_is_interactive = FALSE;

  if (0==strcmp(infname,outfname)) {
    g_critical(_("%s error: input and output filenames are identical: %s"),
            argv0, infname);
    exit(1);
  }
  
  diagdata = g_object_new (DIA_TYPE_DIAGRAM_DATA, NULL);
  ctx = dia_context_new(_("Import"));

  if (!inf->import_func(infname, diagdata, ctx, inf->user_data)) {
    g_critical(_("%s error: need valid input file %s\n"),
            argv0, infname);
    exit(1);
  }

  /* Apply --show-layers */
  if (show_layers)
    handle_show_layers(diagdata, show_layers);

  /* recalculate before export */
  data_update_extents(diagdata);

  /* 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
   */
  if (size) {
    if (ef == filter_export_get_by_name ("png-libart")) /* the warning we get is appropriate, don't cast */
      ef->export_func(diagdata, ctx, outfname, infname, size);
    else {
      g_warning ("--size parameter unsupported for %s filter", 
                 ef->unique_name ? ef->unique_name : "selected");
      ef->export_func(diagdata, ctx, outfname, infname, ef->user_data);
    }
  }
  else
    ef->export_func(diagdata, ctx, outfname, infname, ef->user_data);
  /* if (!quiet) */ fprintf(stdout,
                      _("%s --> %s\n"),
                        infname,outfname);
  g_object_unref(diagdata);
  dia_context_release(ctx);
  return TRUE;
}
Beispiel #8
0
gboolean
app_exit(void)
{
  GList *list;
  GSList *slist;

  /*
   * The following "solves" a crash related to a second call of app_exit,
   * after gtk_main_quit was called. It may be a win32 gtk-1.3.x bug only
   * but the check shouldn't hurt on *ix either.          --hb
   */
  static gboolean app_exit_once = FALSE;

  if (app_exit_once) {
    g_error(_("This shouldn't happen.  Please file a bug report at bugzilla.gnome.org\n"
	      "describing how you caused this message to appear.\n"));
    return FALSE;
  }

  if (diagram_modified_exists()) {
    if (is_integrated_ui ())
    {
      GtkWidget                *dialog;
      int                       result;
      exit_dialog_item_array_t *items  = NULL;
      GList *                   list; 
      Diagram *                 diagram;
      
      dialog = exit_dialog_make (GTK_WINDOW (interface_get_toolbox_shell ()), 
                                _("Exiting Dia"));

      list = dia_open_diagrams();
      while (list)
      {
        diagram = list->data;

        if (diagram_is_modified (diagram))
        {
          const gchar * name = diagram_get_name (diagram);
          const gchar * path = diagram->filename;
          exit_dialog_add_item (dialog, name, path, diagram);
        }

        list = g_list_next (list);
      }

      result = exit_dialog_run (dialog, &items);
  
      gtk_widget_destroy (dialog);

      if (result == EXIT_DIALOG_EXIT_CANCEL)
      {
        return FALSE;
      }
      else if (result == EXIT_DIALOG_EXIT_SAVE_SELECTED)
      {
	    DiaContext *ctx = dia_context_new(_("Save"));
        int i;
        for (i = 0 ; i < items->array_size ; i++) {
	  gchar *filename;

	  diagram  = items->array[i].data;
	  filename = g_filename_from_utf8 (diagram->filename, -1, NULL, NULL, NULL);
	  diagram_update_extents (diagram);
	  dia_context_set_filename (ctx, filename);
	  if (!diagram_save (diagram, filename, ctx)) {
	    exit_dialog_free_items (items);
	    dia_context_release (ctx);
	    return FALSE;
	  } else {
	    dia_context_reset (ctx);
	  }
	  g_free (filename);
	}
	dia_context_release (ctx);
	exit_dialog_free_items (items);
      } 
      else if (result == EXIT_DIALOG_EXIT_NO_SAVE) 
      {
        list = dia_open_diagrams();
        while (list) {
          diagram = list->data;

	  /* slight hack: don't ask again */
          diagram_set_modified (diagram, FALSE);
	  undo_clear(diagram->undo);
          list = g_list_next (list);
	}
      }
    }
    else
    {
    GtkWidget *dialog;
    GtkWidget *button;
    dialog = gtk_message_dialog_new(
	       NULL, GTK_DIALOG_MODAL,
               GTK_MESSAGE_QUESTION,
               GTK_BUTTONS_NONE, /* no standard buttons */
	       _("Quitting without saving modified diagrams"));
    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
		 _("Modified diagrams exist. "
		 "Are you sure you want to quit Dia "
 		 "without saving them?"));

    gtk_window_set_title (GTK_WINDOW(dialog), _("Quit Dia"));
  
    button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
    gtk_dialog_add_action_widget (GTK_DIALOG(dialog), button, GTK_RESPONSE_CANCEL);
#if GTK_CHECK_VERSION(2,18,0)
    gtk_widget_set_can_default (GTK_WIDGET (button), TRUE);
#else
    GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
#endif
    gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);

    button = gtk_button_new_from_stock (GTK_STOCK_QUIT);
    gtk_dialog_add_action_widget (GTK_DIALOG(dialog), button, GTK_RESPONSE_OK);

    gtk_widget_show_all (dialog);

    if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
      gtk_widget_destroy(dialog);
      return FALSE;
    }
    gtk_widget_destroy(dialog);
    }
  }
  prefs_save();

  persistence_save();

  dynobj_refresh_finish();

  {
    DiaContext *ctx = dia_context_new (_("Exit"));
    dia_object_defaults_save (NULL, ctx);
    dia_context_release (ctx);
  }
  /* Free loads of stuff (toolbox) */

  list = dia_open_diagrams();
  while (list!=NULL) {
    Diagram *dia = (Diagram *)list->data;
    list = g_list_next(list);

    slist = dia->displays;
    while (slist!=NULL) {
      DDisplay *ddisp = (DDisplay *)slist->data;
      slist = g_slist_next(slist);

      gtk_widget_destroy(ddisp->shell);
    }
    /* The diagram is freed when the last display is destroyed */
  }
  
  /* save pluginrc */
  if (dia_is_interactive)
    dia_pluginrc_write();

  gtk_main_quit();

  /* This printf seems to prevent a race condition with unrefs. */
  /* Yuck.  -Lars */
  /* Trying to live without it. -Lars 10/8/07*/
  /* g_print(_("Thank you for using Dia.\n")); */
  app_exit_once = TRUE;

  return TRUE;
}
Beispiel #9
0
/**
 * A button hit in the Export Dialog
 */
static void
file_export_response_callback(GtkWidget *fs, 
                              gint       response, 
                              gpointer   user_data)
{
  char *filename;
  Diagram *dia;
  DiaExportFilter *ef;
  struct stat statbuf;

  dia = g_object_get_data (G_OBJECT (fs), "user_data");
  g_assert (dia);

  if (response == GTK_RESPONSE_ACCEPT) {
    gint index;

    diagram_update_extents(dia);

    filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs));

    if (g_stat(filename, &statbuf) == 0) {
      GtkWidget *dialog = NULL;

      dialog = gtk_message_dialog_new (GTK_WINDOW(fs),
				       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 
				       GTK_MESSAGE_QUESTION,
				       GTK_BUTTONS_YES_NO,
				       _("File already exists"));
      gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
        _("The file '%s' already exists.\n"
        "Do you want to overwrite it?"), dia_message_filename(filename));
      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);

      if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_YES) {
	/* if not overwrite allow to select another filename */
	gtk_widget_destroy(dialog);
	g_free (filename);
	return;
      }
      gtk_widget_destroy(dialog);
    }

    index = gtk_combo_box_get_active (GTK_COMBO_BOX(user_data));
    if (index >= 0)
      persistence_set_integer ("export-filter", index);
    ef = efilter_by_index (index - 1, NULL);
    if (!ef)
      ef = filter_guess_export_filter(filename);
    if (ef) {
      DiaContext *ctx = dia_context_new (_("Export"));

      g_object_ref(dia->data);
      dia_context_set_filename (ctx, filename);
      ef->export_func(dia->data, ctx,
		      filename, dia->filename, ef->user_data);
      g_object_unref(dia->data);
      dia_context_release (ctx);
    } else
      message_error(_("Could not determine which export filter\n"
		      "to use to save '%s'"), dia_message_filename(filename));
    g_free (filename);
  }
  g_object_unref (dia); /* drop our diagram reference */
  gtk_widget_destroy(exportdlg);
}
Beispiel #10
0
static GtkWidget *
file_save_as_dialog_prepare (Diagram *dia, DDisplay *ddisp)
{
  gchar *filename = NULL;

  if (!savedlg) {
    GtkWidget *compressbutton;

    savedlg = gtk_file_chooser_dialog_new(_("Save Diagram"),
					  GTK_WINDOW(ddisp->shell),
					  GTK_FILE_CHOOSER_ACTION_SAVE,
					  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
					  NULL);
    /* vfs saving is as easy - if you see 'bad file descriptor' there is
     * something wrong with the permissions of the share ;) */
    gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER(savedlg), FALSE);

    gtk_dialog_set_default_response(GTK_DIALOG(savedlg), GTK_RESPONSE_ACCEPT);
    gtk_window_set_role(GTK_WINDOW(savedlg), "save_diagram");
    /* Need better way to make it a reasonable size.  Isn't there some*/
    /* standard look for them (or is that just Gnome?)*/
    compressbutton = gtk_check_button_new_with_label(_("Compress diagram files"));
    gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(savedlg),
				      compressbutton);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compressbutton),
				 dia->data->is_compressed);
    g_signal_connect(G_OBJECT(compressbutton), "toggled",
		     G_CALLBACK(toggle_compress_callback), NULL);
    gtk_widget_show(compressbutton);
    gtk_widget_set_tooltip_text (compressbutton,
			 _("Compression reduces file size to less than 1/10th "
			   "size and speeds up loading and saving.  Some text "
			   "programs cannot manipulate compressed files."));
    g_signal_connect (GTK_FILE_CHOOSER(savedlg),
		      "response", G_CALLBACK(file_save_as_response_callback), compressbutton);
    g_signal_connect(G_OBJECT(savedlg), "destroy",
		     G_CALLBACK(gtk_widget_destroyed), &savedlg);
  } else {
    GtkWidget *compressbutton = gtk_file_chooser_get_extra_widget(GTK_FILE_CHOOSER(savedlg));
    gtk_widget_set_sensitive(savedlg, TRUE);
    g_signal_handlers_block_by_func(G_OBJECT(compressbutton), toggle_compress_callback, NULL);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compressbutton),
				 dia->data->is_compressed);
    g_signal_handlers_unblock_by_func(G_OBJECT(compressbutton), toggle_compress_callback, NULL);
    if (g_object_get_data (G_OBJECT (savedlg), "user_data") != NULL)
      g_object_unref (g_object_get_data (G_OBJECT (savedlg), "user_data"));
#if GTK_CHECK_VERSION(2,20,0)
    if (gtk_widget_get_visible(savedlg)) {
#else
    if (GTK_WIDGET_VISIBLE(savedlg)) {
#endif
      /* keep a refernce to the diagram */
      g_object_ref(dia);
      g_object_set_data (G_OBJECT (savedlg), "user_data", dia);
      gtk_window_present (GTK_WINDOW(savedlg));
      return savedlg;
    }
  }
  if (dia && dia->filename)
    filename = g_filename_from_utf8(dia->filename, -1, NULL, NULL, NULL);
  if (filename != NULL) {
    char* fnabs = dia_get_absolute_filename (filename);
    if (fnabs) {
      gchar *base = g_path_get_basename(dia->filename);
      gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(savedlg), fnabs);
      /* FileChooser api insist on exiting files for set_filename  */
      /* ... and does not use filename encoding on this one. */
      gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(savedlg), base);
      g_free(base);
    }
    g_free(fnabs);
    g_free(filename);
  }
  g_object_ref(dia);
  g_object_set_data (G_OBJECT (savedlg), "user_data", dia);

  return savedlg;
}

/**
 * Respond to the File/Save menu entry.
 *
 * Delegates to Save As if there is no filename set yet.
 */
void
file_save_callback(GtkAction *action)
{
  Diagram *diagram;

  diagram = ddisplay_active_diagram();
  if (!diagram) return;

  if (diagram->unsaved) {
    file_save_as_callback(action);
  } else {
    gchar *filename = g_filename_from_utf8(diagram->filename, -1, NULL, NULL, NULL);
    DiaContext *ctx = dia_context_new (_("Save"));
    diagram_update_extents(diagram);
    if (diagram_save(diagram, filename, ctx))
      recent_file_history_add(filename);
    g_free (filename);
    dia_context_release (ctx);
  }
}
Beispiel #11
0
/**
 * Respond to a button press (also destroy) in the save as dialog.
 */
static void
file_save_as_response_callback(GtkWidget *fs, 
                               gint       response, 
                               gpointer   user_data)
{
  char *filename;
  Diagram *dia;
  struct stat stat_struct;

  if (response == GTK_RESPONSE_ACCEPT) {
    dia = g_object_get_data (G_OBJECT(fs), "user_data");

    filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs));
    if (!filename) {
      /* Not getting a filename looks like a contract violation in Gtk+ to me.
       * Still Dia would be crashing (bug #651949) - instead simply go back to the dialog. */
      gtk_window_present (GTK_WINDOW (fs));
      return;
    }

    if (g_stat(filename, &stat_struct) == 0) {
      GtkWidget *dialog = NULL;
      char *utf8filename = NULL;
      if (!g_utf8_validate(filename, -1, NULL)) {
	utf8filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
	if (utf8filename == NULL) {
	  message_warning(_("Some characters in the filename are neither UTF-8\n" 
			    "nor your local encoding.\nSome things will break."));
	}
      }
      if (utf8filename == NULL) utf8filename = g_strdup(filename);


      dialog = gtk_message_dialog_new (GTK_WINDOW(fs),
				       GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
				       GTK_BUTTONS_YES_NO,
				       _("File already exists"));
      gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
        _("The file '%s' already exists.\n"
          "Do you want to overwrite it?"), utf8filename);
      g_free(utf8filename);
      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);

      if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_YES) {
	/* don't hide/destroy the dialog, but simply go back to it */
	gtk_window_present (GTK_WINDOW (fs));
	gtk_widget_destroy(dialog);
        g_free (filename);
	return;
      }
      gtk_widget_destroy(dialog);
    }

    dia->data->is_compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(user_data));

    diagram_update_extents(dia);

    {
      DiaContext *ctx = dia_context_new (_("Save as"));
      diagram_set_filename(dia, filename);
      dia_context_set_filename (ctx, filename);
      if (diagram_save(dia, filename, ctx))
	recent_file_history_add(filename);
      dia_context_release (ctx);
    }
    g_free (filename);
  }
  /* if we have our own reference, drop it before destroy */
  if ((dia = g_object_get_data (G_OBJECT(fs), "user_data")) != NULL) {
    g_object_set_data (G_OBJECT(fs), "user_data", NULL);
    g_object_unref (dia);
  }
  /* if we destroy it gtk_dialog_run wont give the response */
  if (!g_object_get_data (G_OBJECT(fs), "dont-destroy"))
    gtk_widget_destroy(GTK_WIDGET(fs));
}