Logo Search packages:      
Sourcecode: xdg-user-dirs-gtk version File versions  Download package

update.c

#include "config.h"

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <libintl.h>
#include <locale.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include "parse.h"

static XdgDirEntry *
find_dir_entry (XdgDirEntry *entries, const char *type)
{
  int i;

  for (i = 0; entries[i].type != NULL; i++)
    {
      if (strcmp (entries[i].type, type) == 0)
      return &entries[i];
    }
  return NULL;
}

static XdgDirEntry *
find_dir_entry_by_path (XdgDirEntry *entries, const char *path)
{
  int i;

  for (i = 0; entries[i].type != NULL; i++)
    {
      if (strcmp (entries[i].path, path) == 0)
      return &entries[i];
    }
  return NULL;
}

static gboolean
has_xdg_translation (void)
{
  char *str;
  const char *locale;

  locale = setlocale (LC_MESSAGES, NULL);

  if (strncmp (locale, "en_US", 5) == 0 ||
      strcmp (locale, "C") == 0)
    return TRUE;
  
  str = "Desktop";
  return dgettext ("xdg-user-dirs", str) != str;
}

static void
update_locale (XdgDirEntry *old_entries)
{
  XdgDirEntry *new_entries, *entry;
  GtkWidget *dialog, *vbox;
  int exit_status;
  int fd;
  char *filename;
  char *cmdline;
  int response;
  int i, j;
  GtkListStore *list_store;
  GtkTreeIter iter;
  GtkWidget *treeview, *check;
  GtkCellRenderer *cell;
  GtkWidget *scrolledwindow;
  GtkWidget *label;
  char *std_out, *std_err;
  gboolean has_changes;

  fd = g_file_open_tmp ("dirs-XXXXXX", &filename, NULL);
  if (fd == -1)
    return;
  close (fd);
  
  cmdline = g_strdup_printf (XDG_USER_DIRS_UPDATE " --force --dummy-output %s", filename);
  if (!g_spawn_command_line_sync  (cmdline, &std_out, &std_err, &exit_status, NULL))
    {
      g_free (std_out);
      g_free (std_err);
      g_free (cmdline);
      g_unlink (filename);
      g_free (filename);
      return;
    }
  g_free (std_out);
  g_free (std_err);
  g_free (cmdline);

  if (!WIFEXITED(exit_status) || WEXITSTATUS(exit_status) != 0)
    return;
  
  new_entries = parse_xdg_dirs (filename);
  g_unlink (filename);
  g_free (filename);

  list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
  has_changes = FALSE;
  for (i = 0; old_entries[i].type != NULL; i++)
    {
      for (j = 0; new_entries[j].type != NULL; j++)
      {
        if (strcmp (old_entries[i].type, new_entries[j].type) == 0)
          break;
      }
      if (new_entries[j].type != NULL &&
        strcmp (old_entries[i].path, new_entries[j].path) != 0)
      {
        char *from, *to;
        from = g_filename_display_name (old_entries[i].path);
        to = g_filename_display_name (new_entries[j].path);

        gtk_list_store_append (list_store, &iter);
        gtk_list_store_set (list_store, &iter,
                        0, from, 1, to, -1);
        
        g_free (from);
        g_free (to);
        
        has_changes = TRUE;
      }
    }
  for (j = 0; new_entries[j].type != NULL; j++)
    {
      for (i = 0; old_entries[i].type != NULL; i++)
      {
        if (strcmp (old_entries[i].type, new_entries[j].type) == 0)
          break;
      }
      if (old_entries[i].type == NULL)
      {
        char *to;
        to = g_filename_display_name (new_entries[j].path);

        gtk_list_store_append (list_store, &iter);
        gtk_list_store_set (list_store, &iter,
                        0, "-", 1, to, -1);

        g_free (to);
        
        has_changes = TRUE;
      }
    }

  if (!has_changes)
    {
      g_object_unref (list_store);
      return;
    }
  
  dialog = gtk_message_dialog_new (NULL, 0,
                           GTK_MESSAGE_WARNING,
                           GTK_BUTTONS_NONE,
                           _("Update standard folders to current language?"));
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                  _("You have logged in in a new language. You can automatically update the names of some standard folders in your home folder to match this language. The update would change the following folders:"));

  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
                    _("_Keep Old Names"), GTK_RESPONSE_NO,
                    _("_Update Names"), GTK_RESPONSE_YES,
                    NULL);

  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO);

  vbox = gtk_vbox_new (FALSE, 6);
  gtk_box_pack_start (GTK_BOX (GTK_MESSAGE_DIALOG (dialog)->label->parent), vbox, TRUE, TRUE, 0);
  gtk_widget_show (vbox);

  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
                          GTK_POLICY_NEVER,
                          GTK_POLICY_NEVER);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
                               GTK_SHADOW_IN);  
  
  gtk_box_pack_start (GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0);
  
  treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));

  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
                               GTK_SELECTION_NONE); 

  cell = gtk_cell_renderer_text_new ();
  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                     -1, _("Current folder name"),
                                     cell,
                                     "text", 0,
                                     NULL);
  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                     -1, _("New folder name"),
                                     cell,
                                     "text", 1,
                                     NULL);

  gtk_container_add (GTK_CONTAINER (scrolledwindow),
                 treeview);

  gtk_widget_show_all (scrolledwindow);

  label = gtk_label_new (_("Note that existing content will not be moved."));
  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
  gtk_label_set_selectable (GTK_LABEL (label), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);

  check = gtk_check_button_new_with_mnemonic (_("_Don't ask me this again"));
  gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
  gtk_widget_show (check);
  
  response =  gtk_dialog_run (GTK_DIALOG (dialog));

  if (response == GTK_RESPONSE_YES)
    {
      if (!g_spawn_command_line_sync (XDG_USER_DIRS_UPDATE " --force", NULL, NULL, &exit_status, NULL) ||
        !WIFEXITED(exit_status) ||
        WEXITSTATUS(exit_status) != 0)
      {
        GtkWidget *error;

        error = gtk_message_dialog_new (NULL, 0,
                                GTK_MESSAGE_ERROR,
                                GTK_BUTTONS_OK,
                                _("There was an error updating the folders"));
        
        gtk_dialog_run (GTK_DIALOG (error));
        gtk_widget_destroy (error);
      }
      else
      {
        /* Change succeeded, remove any leftover empty directories */
        for (i = 0; old_entries[i].type != NULL; i++)
          {
            /* Never remove homedir */
            if (strcmp (old_entries[i].path, g_get_home_dir ()) == 0)
            continue;
            
            /* If the old path is used by the new config, don't remove */
            entry = find_dir_entry_by_path (new_entries, old_entries[i].path);
            if (entry)
            continue;

            /* Remove the dir, will fail if not empty */
            g_rmdir (old_entries[i].path);
          }
      }
    }

  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)))
    {
      char *file;
      
      file = g_build_filename (g_get_user_config_dir (),
                         "user-dirs.locale", NULL);
      g_unlink (file);
      g_free (file);
    }

  g_free (new_entries);

  gtk_widget_destroy (dialog);
  g_object_unref (list_store);
}

int
main (int argc, char *argv[])
{
  XdgDirEntry *old_entries, *new_entries, *entry;
  XdgDirEntry *desktop_entry;
  GtkBookmark *bookmark;
  GList *bookmarks, *l;
  char *old_locale;
  char *locale, *dot;
  int i;
  gboolean modified_bookmarks;
  char *uri;
  
  setlocale (LC_ALL, "");
  
  bindtextdomain (GETTEXT_PACKAGE, GLIBLOCALEDIR);
  bindtextdomain ("xdg-user-dirs", GLIBLOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);

  gtk_init (&argc, &argv);

  old_entries = parse_xdg_dirs (NULL);
  old_locale = parse_xdg_dirs_locale ();
  locale = g_strdup (setlocale (LC_MESSAGES, NULL));
  dot = strchr (locale, '.');
  if (dot)
    *dot = 0;

  if (old_locale && *old_locale != 0 &&
      strcmp (old_locale, locale) != 0 &&
      has_xdg_translation ())
    update_locale (old_entries);

  new_entries = parse_xdg_dirs (NULL);

  bookmarks = parse_gtk_bookmarks (NULL);

  modified_bookmarks = FALSE;
  if (bookmarks == NULL)
    {
      char *make_bm_for[] = {
      "DOCUMENTS",
      "MUSIC",
      "PICTURES",
      "VIDEOS",
      "DOWNLOAD",
      NULL};
      /* No previous bookmarks. Generate standard ones */

      desktop_entry = find_dir_entry (new_entries, "DESKTOP");
      for (i = 0; make_bm_for[i] != NULL; i++)
      {
        entry = find_dir_entry (new_entries, make_bm_for[i]);
        
        if (entry && strcmp (entry->path, g_get_home_dir ()) != 0 &&
            (desktop_entry == NULL || strcmp (entry->path, desktop_entry->path) != 0))
          {
            uri = g_filename_to_uri (entry->path, NULL, NULL);
            if (uri)
            {
              modified_bookmarks = TRUE;
              bookmark = g_new0 (GtkBookmark, 1);
              bookmark->uri = uri;
              bookmarks = g_list_append (bookmarks, bookmark);
            }
          }
      }
    }
  else
    {
      /* Map old bookmarks that were moved */

      for (l = bookmarks; l != NULL; l = l->next)
      {
        char *path;
        
        bookmark = l->data;

        path = g_filename_from_uri (bookmark->uri, NULL, NULL);
        if (path)
          {
            entry = find_dir_entry_by_path (old_entries, path);
            if (entry)
            {
              entry = find_dir_entry (new_entries, entry->type);
              if (entry)
                {
                  uri = g_filename_to_uri (entry->path, NULL, NULL);
                  if (uri)
                  {
                    modified_bookmarks = TRUE;
                    g_free (bookmark->uri);
                    bookmark->uri = uri;
                  }
                }
            }
            g_free (path);
          }
      }
    }

  if (modified_bookmarks)
    save_gtk_bookmarks (NULL, bookmarks);
  
  g_free (new_entries);
  g_free (old_entries);
  
  return 0;
}

Generated by  Doxygen 1.6.0   Back to index