Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  gtkbookmarksmanager.c

  Sprache: C
 

/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
/* GTK - The GIMP Toolkit
 * gtkbookmarksmanager.c: Utilities to manage and monitor ~/.gtk-bookmarks
 * Copyright (C) 2003, Red Hat, Inc.
 * Copyright (C) 2007-2008 Carlos Garnacho
 * Copyright (C) 2011 Suse
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Federico Mena Quintero <federico@gnome.org>
 */


#include "config.h"

#include <string.h>

#include <glib/gi18n-lib.h>

#include "gtkbookmarksmanagerprivate.h"
#include "deprecated/gtkfilechooser.h" /* for the GError types */

G_GNUC_BEGIN_IGNORE_DEPRECATIONS

static void
_gtk_bookmark_free (gpointer data)
{
  GtkBookmark *bookmark = data;

  g_object_unref (bookmark->file);
  g_free (bookmark->label);
  g_free (bookmark);
}

static void
set_error_bookmark_doesnt_exist (GFile *file, GError **error)
{
  char *uri = g_file_get_uri (file);

  g_set_error (error,
               GTK_FILE_CHOOSER_ERROR,
               GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
               _("%s does not exist in the bookmarks list"),
               uri);

  g_free (uri);
}

static GFile *
get_legacy_bookmarks_file (void)
{
  GFile *file;
  char *filename;

  filename = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);
  file = g_file_new_for_path (filename);
  g_free (filename);

  return file;
}

static GFile *
get_bookmarks_file (void)
{
  GFile *file;
  char *filename;

  /* Use gtk-3.0's bookmarks file as the format didn't change.
   * Add the 3.0 file format to get_legacy_bookmarks_file() when
   * the format does change.
   */

  filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0""bookmarks", NULL);
  file = g_file_new_for_path (filename);
  g_free (filename);

  return file;
}

static GSList *
parse_bookmarks (const char *contents)
{
  char **lines, *space;
  GSList *bookmarks = NULL;
  int i;

  lines = g_strsplit (contents, "\n", -1);

  for (i = 0; lines[i]; i++)
    {
      GtkBookmark *bookmark;

      if (!*lines[i])
 continue;

      if (!g_utf8_validate (lines[i], -1, NULL))
 continue;

      bookmark = g_new0 (GtkBookmark, 1);

      if ((space = strchr (lines[i], ' ')) != NULL)
 {
   space[0] = '\0';
   bookmark->label = g_strdup (space + 1);
 }

      bookmark->file = g_file_new_for_uri (lines[i]);
      bookmarks = g_slist_prepend (bookmarks, bookmark);
    }

  bookmarks = g_slist_reverse (bookmarks);
  g_strfreev (lines);

  return bookmarks;
}

static GSList *
read_bookmarks (GFile *file)
{
  char *contents;
  GSList *bookmarks = NULL;

  if (!g_file_load_contents (file, NULL, &contents,
        NULL, NULL, NULL))
    return NULL;

  bookmarks = parse_bookmarks (contents);

  g_free (contents);

  return bookmarks;
}

static void
notify_changed (GtkBookmarksManager *manager)
{
  if (manager->changed_func)
    manager->changed_func (manager->changed_func_data);
}

static void
read_bookmarks_finish (GObject      *source,
                       GAsyncResult *result,
                       gpointer      data)
{
  GFile *file = G_FILE (source);
  GtkBookmarksManager *manager = data;
  char *contents = NULL;
  GError *error = NULL;

  if (!g_file_load_contents_finish (file, result, &contents, NULL, NULL, &error)) 
    {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        g_warning ("Failed to load '%s': %s", g_file_peek_path (file), error->message);
      g_error_free (error);
      return;
    }

  g_slist_free_full (manager->bookmarks, _gtk_bookmark_free);
  manager->bookmarks = parse_bookmarks (contents);

  g_free (contents);

  notify_changed (manager);
}

static void
save_bookmarks (GFile  *bookmarks_file,
  GSList *bookmarks)
{
  GError *error = NULL;
  GString *contents;
  GSList *l;
  GFile *parent = NULL;

  contents = g_string_new ("");

  for (l = bookmarks; l; l = l->next)
    {
      GtkBookmark *bookmark = l->data;
      char *uri;

      uri = g_file_get_uri (bookmark->file);
      if (!uri)
 continue;

      g_string_append (contents, uri);

      if (bookmark->label && g_utf8_validate (bookmark->label, -1, NULL))
 g_string_append_printf (contents, " %s", bookmark->label);

      g_string_append_c (contents, '\n');
      g_free (uri);
    }

  parent = g_file_get_parent (bookmarks_file);
  if (!g_file_make_directory_with_parents (parent, NULL, &error))
    {
       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
  g_clear_error (&error);
       else
  goto out;
    }
  if (!g_file_replace_contents (bookmarks_file,
    contents->str,
    contents->len,
    NULL, FALSE0, NULL,
    NULL, &error))
    goto out;

 out:
  if (error)
    {
      g_critical ("%s", error->message);
      g_error_free (error);
    }
  g_clear_object (&parent);
  g_string_free (contents, TRUE);
}

static void
bookmarks_file_changed (GFileMonitor      *monitor,
   GFile             *file,
   GFile             *other_file,
   GFileMonitorEvent  event,
   gpointer           data)
{
  GtkBookmarksManager *manager = data;

  switch (event)
    {
    case G_FILE_MONITOR_EVENT_CHANGED:
    case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
    case G_FILE_MONITOR_EVENT_CREATED:
      g_file_load_contents_async (file, manager->cancellable, read_bookmarks_finish, manager);
      break;

    case G_FILE_MONITOR_EVENT_DELETED:
    case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
    case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
    case G_FILE_MONITOR_EVENT_UNMOUNTED:
    case G_FILE_MONITOR_EVENT_MOVED:
    case G_FILE_MONITOR_EVENT_RENAMED:
    case G_FILE_MONITOR_EVENT_MOVED_IN:
    case G_FILE_MONITOR_EVENT_MOVED_OUT:
    default:
      /* ignore at the moment */
      break;
    }
}

GtkBookmarksManager *
_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func, gpointer changed_func_data)
{
  GtkBookmarksManager *manager;
  GFile *bookmarks_file;
  GError *error;

  manager = g_new0 (GtkBookmarksManager, 1);

  manager->changed_func = changed_func;
  manager->changed_func_data = changed_func_data;

  manager->cancellable = g_cancellable_new ();

  bookmarks_file = get_bookmarks_file ();
  if (!g_file_query_exists (bookmarks_file, NULL))
    {
      GFile *legacy_bookmarks_file;

      /* Read the legacy one and write it to the new one */
      legacy_bookmarks_file = get_legacy_bookmarks_file ();
      manager->bookmarks = read_bookmarks (legacy_bookmarks_file);
      if (manager->bookmarks)
 save_bookmarks (bookmarks_file, manager->bookmarks);

      g_object_unref (legacy_bookmarks_file);
    }
  else
    g_file_load_contents_async (bookmarks_file, manager->cancellable, read_bookmarks_finish, manager);

  error = NULL;
  manager->bookmarks_monitor = g_file_monitor_file (bookmarks_file,
          G_FILE_MONITOR_NONE,
          NULL, &error);
  if (error)
    {
      g_warning ("%s", error->message);
      g_error_free (error);
    }
  else
    manager->bookmarks_monitor_changed_id = g_signal_connect (manager->bookmarks_monitor, "changed",
             G_CALLBACK (bookmarks_file_changed), manager);


  g_object_unref (bookmarks_file);

  return manager;
}

void
_gtk_bookmarks_manager_free (GtkBookmarksManager *manager)
{
  g_return_if_fail (manager != NULL);

  g_cancellable_cancel (manager->cancellable);
  g_object_unref (manager->cancellable);

  if (manager->bookmarks_monitor)
    {
      g_file_monitor_cancel (manager->bookmarks_monitor);
      g_clear_signal_handler (&manager->bookmarks_monitor_changed_id, manager->bookmarks_monitor);
      g_object_unref (manager->bookmarks_monitor);
    }

  g_slist_free_full (manager->bookmarks, _gtk_bookmark_free);

  g_free (manager);
}

GSList *
_gtk_bookmarks_manager_list_bookmarks (GtkBookmarksManager *manager)
{
  GSList *bookmarks, *files = NULL;

  g_return_val_if_fail (manager != NULL, NULL);

  bookmarks = manager->bookmarks;

  while (bookmarks)
    {
      GtkBookmark *bookmark;

      bookmark = bookmarks->data;
      bookmarks = bookmarks->next;

      files = g_slist_prepend (files, g_object_ref (bookmark->file));
    }

  return g_slist_reverse (files);
}

static GSList *
find_bookmark_link_for_file (GSList *bookmarks, GFile *file, int *position_ret)
{
  int pos;

  pos = 0;
  for (; bookmarks; bookmarks = bookmarks->next)
    {
      GtkBookmark *bookmark = bookmarks->data;

      if (g_file_equal (file, bookmark->file))
 {
   if (position_ret)
     *position_ret = pos;

   return bookmarks;
 }

      pos++;
    }

  if (position_ret)
    *position_ret = -1;

  return NULL;
}

gboolean
_gtk_bookmarks_manager_has_bookmark (GtkBookmarksManager *manager,
                                     GFile               *file)
{
  GSList *link;

  link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
  return (link != NULL);
}

gboolean
_gtk_bookmarks_manager_insert_bookmark (GtkBookmarksManager *manager,
     GFile               *file,
     int                  position,
     GError             **error)
{
  GSList *link;
  GtkBookmark *bookmark;
  GFile *bookmarks_file;

  g_return_val_if_fail (manager != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);

  if (link)
    {
      char *uri;
      bookmark = link->data;
      uri = g_file_get_uri (bookmark->file);

      g_set_error (error,
     GTK_FILE_CHOOSER_ERROR,
     GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
     _("%s already exists in the bookmarks list"),
     uri);

      g_free (uri);

      return FALSE;
    }

  bookmark = g_new0 (GtkBookmark, 1);
  bookmark->file = g_object_ref (file);

  manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, position);

  bookmarks_file = get_bookmarks_file ();
  save_bookmarks (bookmarks_file, manager->bookmarks);
  g_object_unref (bookmarks_file);

  notify_changed (manager);

  return TRUE;
}

gboolean
_gtk_bookmarks_manager_remove_bookmark (GtkBookmarksManager *manager,
     GFile               *file,
     GError             **error)
{
  GSList *link;
  GFile *bookmarks_file;

  g_return_val_if_fail (manager != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (!manager->bookmarks)
    return FALSE;

  link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
  if (link)
    {
      GtkBookmark *bookmark = link->data;

      manager->bookmarks = g_slist_remove_link (manager->bookmarks, link);
      _gtk_bookmark_free (bookmark);
      g_slist_free_1 (link);
    }
  else
    {
      set_error_bookmark_doesnt_exist (file, error);
      return FALSE;
    }

  bookmarks_file = get_bookmarks_file ();
  save_bookmarks (bookmarks_file, manager->bookmarks);
  g_object_unref (bookmarks_file);

  notify_changed (manager);

  return TRUE;
}

gboolean
_gtk_bookmarks_manager_reorder_bookmark (GtkBookmarksManager *manager,
      GFile               *file,
      int                  new_position,
      GError             **error)
{
  GSList *link;
  GFile *bookmarks_file;
  int old_position;

  g_return_val_if_fail (manager != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
  g_return_val_if_fail (new_position >= 0FALSE);

  if (!manager->bookmarks)
    return FALSE;

  link = find_bookmark_link_for_file (manager->bookmarks, file, &old_position);
  if (new_position == old_position)
    return TRUE;

  if (link)
    {
      GtkBookmark *bookmark = link->data; 

      manager->bookmarks = g_slist_remove_link (manager->bookmarks, link);
      g_slist_free_1 (link);

      if (new_position > old_position)
 new_position--;

      manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, new_position);
    }
  else
    {
      set_error_bookmark_doesnt_exist (file, error);
      return FALSE;
    }

  bookmarks_file = get_bookmarks_file ();
  save_bookmarks (bookmarks_file, manager->bookmarks);
  g_object_unref (bookmarks_file);

  notify_changed (manager);

  return TRUE;
}

char *
_gtk_bookmarks_manager_get_bookmark_label (GtkBookmarksManager *manager,
        GFile               *file)
{
  GSList *bookmarks;
  char *label = NULL;

  g_return_val_if_fail (manager != NULL, NULL);
  g_return_val_if_fail (file != NULL, NULL);

  bookmarks = manager->bookmarks;

  while (bookmarks)
    {
      GtkBookmark *bookmark;

      bookmark = bookmarks->data;
      bookmarks = bookmarks->next;

      if (g_file_equal (file, bookmark->file))
 {
   label = g_strdup (bookmark->label);
   break;
 }
    }

  return label;
}

gboolean
_gtk_bookmarks_manager_set_bookmark_label (GtkBookmarksManager *manager,
        GFile               *file,
        const char          *label,
        GError             **error)
{
  GFile *bookmarks_file;
  GSList *link;

  g_return_val_if_fail (manager != NULL, FALSE);
  g_return_val_if_fail (file != NULL, FALSE);

  link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
  if (link)
    {
      GtkBookmark *bookmark = link->data;

      g_free (bookmark->label);
      bookmark->label = g_strdup (label);
    }
  else
    {
      set_error_bookmark_doesnt_exist (file, error);
      return FALSE;
    }

  bookmarks_file = get_bookmarks_file ();
  save_bookmarks (bookmarks_file, manager->bookmarks);
  g_object_unref (bookmarks_file);

  notify_changed (manager);

  return TRUE;
}

static gboolean
_gtk_bookmarks_manager_get_xdg_type (GtkBookmarksManager *manager,
                                     GFile               *file,
                                     GUserDirectory      *directory)
{
  GSList *link;
  gboolean match;
  GFile *location;
  const char *path;
  GUserDirectory dir;
  GtkBookmark *bookmark;

  link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
  if (!link)
    return FALSE;

  match = FALSE;
  bookmark = link->data;

  for (dir = 0; dir < G_USER_N_DIRECTORIES; dir++)
    {
      path = g_get_user_special_dir (dir);
      if (!path)
        continue;

      location = g_file_new_for_path (path);
      match = g_file_equal (location, bookmark->file);
      g_object_unref (location);

      if (match)
        break;
    }

  if (match && directory != NULL)
    *directory = dir;

  return match;
}

gboolean
_gtk_bookmarks_manager_get_is_builtin (GtkBookmarksManager *manager,
                                       GFile               *file)
{
  GUserDirectory xdg_type;

  /* if this is not an XDG dir, it's never builtin */
  if (!_gtk_bookmarks_manager_get_xdg_type (manager, file, &xdg_type))
    return FALSE;

  /* exclude XDG locations we don't display by default */
  return _gtk_bookmarks_manager_get_is_xdg_dir_builtin (xdg_type);
}

gboolean
_gtk_bookmarks_manager_get_is_xdg_dir_builtin (GUserDirectory xdg_type)
{
  return (xdg_type != G_USER_DIRECTORY_DESKTOP) &&
    (xdg_type != G_USER_DIRECTORY_TEMPLATES) &&
    (xdg_type != G_USER_DIRECTORY_PUBLIC_SHARE);
}

Messung V0.5 in Prozent
C=98 H=95 G=96

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik