Logo Search packages:      
Sourcecode: netbook-launcher version File versions

launcher-sidebar.c

/*
 * Copyright (C) 2008 Canonical Ltd
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as 
 * published by the Free Software Foundation.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authored by Neil Jagdish Patel <neil.patel@canonical.com>
 *
 */

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <gconf/gconf.h>
#include <gconf/gconf-client.h>

#include "launcher-sidebar.h"

#include <gio/gio.h>
#include <glib/gi18n.h>
#include <string.h>
#include <tidy/tidy.h>

#include "clutter-focus-group.h"

#include "launcher-config.h"
#include "launcher-defines.h"
#include "clutter-drag-dest.h"
#include "clutter-drag-server.h"
#include "launcher-icon.h"
#include "launcher-shortcut.h"
#include "launcher-notify.h"
#include "launcher-util.h"

static void clutter_focus_group_iface_init (ClutterFocusGroupIface *iface);
static void on_link_clicked (ClutterActor *shortcut, gpointer null);

G_DEFINE_TYPE_WITH_CODE (LauncherSidebar, 
                         launcher_sidebar, 
                         CLUTTER_TYPE_GROUP,
                         G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_FOCUS_GROUP,
                                              clutter_focus_group_iface_init));


#define LAUNCHER_SIDEBAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
  LAUNCHER_TYPE_SIDEBAR, \
  LauncherSidebarPrivate))

#define NAUTILUS  "nautilus --no-desktop --browser %s"

struct _LauncherSidebarPrivate
{
  GVolumeMonitor *monitor;
  GFile          *bookfile;
  GFileMonitor   *bookfile_mon;

  ClutterActor   *bg;
  ClutterActor   *clip;
  ClutterActor   *grid;
  ClutterActor   *scroll;
  TidyAdjustment *adjust;

  GList *shortcuts;
  GList *links;
  GList *places;

  GSList *excluded_volumes;

  ClutterActor *trash;
  ClutterActor *focused;

  ClutterTimeline *timeline;
  ClutterEffectTemplate *temp;
};

gboolean
launcher_sidebar_scroll_event (ClutterActor       *actor,
                              ClutterScrollEvent *event,
                              LauncherSidebar     *bar)
{
  TidyAdjustment *adjust;
  LauncherConfig *cfg = launcher_config_get_default ();
  gdouble diff = cfg->shortcut_height;
  gdouble lower, upper;

  if (!LAUNCHER_IS_SIDEBAR (bar)) return FALSE;
  adjust = bar->priv->adjust;

  if (!TIDY_IS_ADJUSTMENT (adjust))
    return TRUE;

  if (event->direction == CLUTTER_SCROLL_UP)
    diff = -cfg->icon_height;

  diff += tidy_adjustment_get_value (adjust);

  tidy_adjustment_get_values (adjust, NULL, &lower, &upper, NULL, NULL, NULL);

  diff = CLAMP (diff, lower, upper);

  tidy_adjustment_set_value (adjust, diff);

  return TRUE;
}
static void
ensure_layout (LauncherSidebar *bar)
{
  LauncherSidebarPrivate *priv;
  LauncherConfig *cfg = launcher_config_get_default ();
  TidyAdjustment *adjustment;
  ClutterActor *scroll, *tex, *frame;
  GList *s;
  gint bar_width = cfg->bar_width;
  gint bar_height = cfg->shortcut_height;
  gint offset = 0;
  gint i = 0;

  g_return_if_fail (LAUNCHER_IS_SIDEBAR (bar));
  priv = bar->priv;

  /* Check trash is on the end of the elements */
  if (LAUNCHER_IS_SHORTCUT (priv->trash))
  {
    if (g_list_last (priv->shortcuts)->data != priv->trash)
    {
      priv->shortcuts = g_list_remove (priv->shortcuts, priv->trash);
      priv->shortcuts = g_list_append (priv->shortcuts, priv->trash);
    }
  }

  for (s = priv->shortcuts; s; s = s->next)
  {
    ClutterActor *actor = s->data;

    if (!CLUTTER_IS_ACTOR (actor))
      continue;
    
    clutter_actor_set_position (actor, 0, offset);

    offset += bar_height;
    i++;
  }

  for (s = priv->places; s; s = s->next)
  {
    ClutterActor *actor = s->data;

    if (!CLUTTER_IS_ACTOR (actor))
      continue;

    clutter_actor_set_position (actor, 0, offset);

    offset += bar_height;
    i++;
  }
  
  clutter_actor_set_size (priv->grid, bar_width, i * bar_height);

  if (i > N_CATS-2)
  {
    tidy_scrollable_get_adjustments (TIDY_SCROLLABLE (priv->grid), 
                                     NULL, &adjustment);
    priv->adjust = adjustment;
    tidy_adjustment_set_values (adjustment, 
                                0,
                                0, i * bar_height,
                                bar_height,
                                1 * bar_width,
                                (N_CATS-2) * bar_height);

    if (priv->scroll)
    {
      tidy_scroll_bar_set_adjustment (TIDY_SCROLL_BAR (priv->scroll), 
                                      adjustment);
      return;
    }
    tex = launcher_util_texture_new_from_file (PKGDATADIR"/scrollbar.svg");
    clutter_actor_set_opacity (tex, 0);
    clutter_container_add_actor (CLUTTER_CONTAINER (priv->grid), tex);
    
    frame = tidy_texture_frame_new (CLUTTER_TEXTURE (tex), 5, 5, 5, 5);
    clutter_actor_set_reactive (CLUTTER_ACTOR (frame), TRUE);
    g_signal_connect (frame, "scroll-event",
                      G_CALLBACK (launcher_sidebar_scroll_event), adjustment); 
        
    scroll = priv->scroll = tidy_scroll_bar_new_with_handle (priv->adjust, 
                                                             frame);
    
    frame = tidy_texture_frame_new (CLUTTER_TEXTURE (tex), 5, 5, 5, 5);
    clutter_actor_set_reactive (CLUTTER_ACTOR (frame), TRUE);
    g_signal_connect (frame, "scroll-event",
                      G_CALLBACK (launcher_sidebar_scroll_event), adjustment);
    clutter_actor_set_reactive (CLUTTER_ACTOR (scroll), TRUE);
    g_signal_connect (scroll, "scroll-event",
                      G_CALLBACK (launcher_sidebar_scroll_event), adjustment);
    clutter_actor_set_opacity (frame, 100);
    tidy_scroll_bar_set_texture (TIDY_SCROLL_BAR (scroll), frame);

    clutter_container_add_actor (CLUTTER_CONTAINER (priv->clip), scroll);
    clutter_actor_set_size (scroll, bar_height * (N_CATS-2) -2, 5);
    clutter_actor_set_anchor_point_from_gravity (scroll, 
                                                 CLUTTER_GRAVITY_CENTER);
    clutter_actor_set_position (scroll, 
                                bar_width- 10/2,
                                ((bar_height*(N_CATS-2))/2) + 2);
    clutter_actor_set_opacity (scroll, 100);
    clutter_actor_set_rotation (scroll, CLUTTER_Z_AXIS, 90, 0, 0, 0);
    clutter_actor_show (scroll);
  }  
  else if (CLUTTER_IS_ACTOR (priv->scroll))
  {
    clutter_actor_set_opacity (priv->scroll, 0);
  }
}


/*
 * PLACES 
 */
static ClutterActor * 
add_place (LauncherSidebar *sidebar, 
           const gchar *icon_name, 
           const gchar *name,
           const gchar *command)
{
  LauncherSidebarPrivate *priv = sidebar->priv;
  ClutterActor *shortcut;
   
  shortcut = launcher_shortcut_new (icon_name, name, FALSE);
  clutter_container_add_actor (CLUTTER_CONTAINER (priv->grid), shortcut);
  clutter_actor_set_name (shortcut, command);
  clutter_actor_show (shortcut);
  priv->places = g_list_append (priv->places, shortcut);
  g_signal_connect (shortcut, "clicked", G_CALLBACK (on_link_clicked), NULL);
  
  return shortcut;
}

static void
load_places (LauncherSidebar *bar)
{
  LauncherSidebarPrivate *priv = bar->priv;
  gchar *path, *contents;

  path = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);

  /* Remove the old places */
  g_list_foreach (priv->places, (GFunc)clutter_actor_destroy, NULL);
  g_list_free (priv->places);
  priv->places = NULL;

  if (!g_file_test (path, G_FILE_TEST_EXISTS))
  {
    g_debug ("No gtk-bookmarks file. Cannot load places");
    g_free (path);
    return;
  }
  
  if (!g_file_get_contents (path, &contents, NULL, NULL))
  {
    g_debug ("Unable to read gtk-bookmarks file");
    g_free (path);
    return;
  }

  if (contents)
  {
    gchar **bookmarks;
    gint i;

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

    for (i = 0; bookmarks[i]; i++)
    {
      const gchar *icon_name = "folder";
      gchar *label;

      label = strchr (bookmarks[i], ' ');
      if (label)
      {
        *label = '\0';
        label++;
      }
      else
      {
        label = strrchr (bookmarks[i], '/');
        if (label)
          label++;
      }
      if ((!label || !label[0]) 
           && !g_ascii_strcasecmp (bookmarks[i], "network:///"))
      {
        label = _("Network");
        icon_name = "gnome-fs-network";
      }
      
      if (label)
      {
        path = g_strdup_printf (NAUTILUS, bookmarks[i]);
        add_place (bar, icon_name, label, path);
        g_free (path);
      }
    }
    g_strfreev (bookmarks);
    g_free (contents);
  }

  ensure_layout (bar);
}

static void
on_places_changed (GFileMonitor      *monitor,
                   GFile             *file,
                   GFile             *old_file,
                   GFileMonitorEvent *event,
                   LauncherSidebar   *bar)
{
  g_return_if_fail (LAUNCHER_IS_SIDEBAR (bar));

  load_places (bar);
}

/*
 * VOLUMES
 */
static gboolean
volume_is_excluded (LauncherSidebar *bar, GVolume *volume)
{
  LauncherSidebarPrivate *priv = bar->priv;
  GSList *v;
  gchar *uid;

  uid = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);

  if (!uid)
    return FALSE;

  for (v = priv->excluded_volumes; v; v = v->next)
  {
    if (v->data && strstr (uid, v->data))
    {
      g_free (uid);
      return TRUE;
    }
  }

  g_free (uid);
  return FALSE;
}


static gboolean
can_eject (GVolume *volume)
{

  if (!G_IS_VOLUME (volume))
  {
    return FALSE;
  }
  else if (g_volume_can_eject (volume))
  {
    return TRUE;
  }
  else if (g_volume_get_mount (volume))
  {
    return TRUE;
  }
  return FALSE;
}

static void
on_volume_mounted (GVolume          *volume,
                   GAsyncResult     *res,
                   LauncherShortcut *shortcut)
{
  gboolean success;
  GMount *mount;
  GFile *root;
  gchar *path, *command;
  
  g_return_if_fail (G_IS_VOLUME (volume));

  success = g_volume_mount_finish (volume, res, NULL);
  
  if (!success)
    return;

  launcher_shortcut_set_active (LAUNCHER_SHORTCUT (shortcut), FALSE);

  mount = g_volume_get_mount (volume);
  if (!G_IS_MOUNT (mount))
  {
    return;
  }

  root = g_mount_get_root (mount);
  path = g_file_get_path (root);
  command = g_strdup_printf (NAUTILUS, path);

  gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
                                    command, NULL);

  g_free (command);
  g_free (path);
}

static void
on_volume_clicked (ClutterActor *shortcut, GVolume *volume)
{
  GMount *mount;
  GFile *root;
  gchar *path, *command;
  ClutterTexture *temp;
  
  g_return_if_fail (G_IS_VOLUME (volume));

  mount = g_volume_get_mount (volume);
  if (!G_IS_MOUNT (mount))
  {
    if (!g_volume_can_mount (volume))
      return;

    g_volume_mount (volume, 0, NULL, NULL, 
                    (GAsyncReadyCallback)on_volume_mounted, shortcut);

    return;
  }

  root = g_mount_get_root (mount);
  path = g_file_get_uri (root);
  command = g_strdup_printf (NAUTILUS, path);

  gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
                                    command, NULL);

  /* Notify the user */
  temp = launcher_shortcut_get_texture (LAUNCHER_SHORTCUT (shortcut));
  launcher_notify_popup (launcher_notify_get_default (),
                  launcher_shortcut_get_label (LAUNCHER_SHORTCUT (shortcut)),
                         CLUTTER_TEXTURE (temp), 
                         -1);

  g_free (command);
  g_free (path);
}

static void
on_eject_clicked (ClutterActor *shortcut, GVolume *volume)
{
  g_return_if_fail (G_IS_VOLUME (volume));

  if (g_volume_can_eject (volume))
  {
    g_volume_eject (volume, 0, NULL, NULL, NULL);
  }
  else
  {
    GMount *mount = g_volume_get_mount (volume);

    if (!mount)
      return;
    g_mount_unmount (mount, 0, NULL, NULL, NULL);
  }
}

static void
on_link_clicked (ClutterActor *shortcut, gpointer null)
{
  const gchar *command;
  ClutterTexture *temp;

  launcher_shortcut_set_active (LAUNCHER_SHORTCUT (shortcut), FALSE);

  command = clutter_actor_get_name (shortcut);

  if (command)
    gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
                                      command, NULL);

  /* Notify the user */
  temp = launcher_shortcut_get_texture (LAUNCHER_SHORTCUT (shortcut));
  launcher_notify_popup (launcher_notify_get_default (),
                  launcher_shortcut_get_label (LAUNCHER_SHORTCUT (shortcut)),
                         temp, 
                         -1);
}

static void
on_trash_clicked (ClutterActor *shortcut, gpointer null)
{
  launcher_shortcut_set_active (LAUNCHER_SHORTCUT (shortcut), FALSE);
}

/* Taken from nautilus::panel-util.c, with some modifications */
static gchar *
get_icon_name (GVolume *volume)
{
  GIcon *icon;
  const gchar * const *names;
  GtkIconTheme *icon_theme;
  int i;

  icon = g_volume_get_icon (volume);

  if (!G_IS_THEMED_ICON (icon))
    return g_strdup ("gnome-fs-folder");

  names = g_themed_icon_get_names (G_THEMED_ICON (icon));
  icon_theme = gtk_icon_theme_get_default ();

  for (i = 0; names[i] != NULL; i++)
  {
    if (gtk_icon_theme_has_icon (icon_theme, names[i]))
          return g_strdup (names[i]);
  }

  return NULL;
}

static void
on_volume_removed (GVolume *volume, LauncherShortcut *shortcut)
{
  LauncherSidebar *bar = g_object_get_data (G_OBJECT (shortcut), "bar");
  
  g_return_if_fail (LAUNCHER_IS_SIDEBAR (bar));

  g_debug ("Volume removed: %s", g_volume_get_name (volume));

  bar->priv->shortcuts = g_list_remove (bar->priv->shortcuts, shortcut);
  clutter_actor_destroy (CLUTTER_ACTOR (shortcut));

  ensure_layout (bar);
}

static void
on_volume_changed (GVolume *volume, LauncherShortcut *shortcut)
{
  g_return_if_fail (LAUNCHER_IS_SHORTCUT (shortcut));
  
  launcher_shortcut_set_can_eject (shortcut, can_eject (volume));
}

static void
on_volume_added (GVolumeMonitor *monitor,
                 GVolume *volume, 
                 LauncherSidebar *sidebar)
{ 
  LauncherSidebarPrivate *priv;
  GMount *mount;
  ClutterActor *shortcut;
  gchar *icon_name = NULL;

  g_return_if_fail (LAUNCHER_IS_SIDEBAR (sidebar));
  priv = sidebar->priv;

  g_debug ("Volume Added: %s %s", 
           g_volume_get_name (volume),
           g_volume_get_identifier (volume, 
                                    G_VOLUME_IDENTIFIER_KIND_HAL_UDI));

  mount = g_volume_get_mount (volume);

  icon_name = get_icon_name (volume);
  shortcut = launcher_shortcut_new (icon_name, 
                                    g_volume_get_name (volume),
                                    can_eject (volume));
  
  clutter_container_add_actor (CLUTTER_CONTAINER (priv->grid), shortcut);
  g_object_set_data (G_OBJECT (shortcut), "volume", volume);
  g_object_set_data (G_OBJECT (shortcut), "bar", sidebar);
  clutter_actor_show (shortcut);

  g_signal_connect (shortcut, "clicked", 
                    G_CALLBACK (on_volume_clicked), volume);
  g_signal_connect (shortcut, "eject", 
                    G_CALLBACK (on_eject_clicked), volume);
  
  g_signal_connect (volume, "changed", 
                    G_CALLBACK (on_volume_changed), shortcut);
  g_signal_connect (volume, "removed", 
                    G_CALLBACK (on_volume_removed), shortcut);
  
  priv->shortcuts = g_list_append (priv->shortcuts, shortcut);

  ensure_layout (sidebar);

  g_free (icon_name);
}
/*
 * /VOLUMES
 */

/*
 * Remove favourite stuff 
 */
static gboolean
on_trashed (ClutterDragDest *dest, gpointer data)
{
  LauncherMenuApplication *app = data;

  if (!app)
    return FALSE;

  launcher_util_remove_favorite (app);
  clutter_drag_dest_finish (dest, TRUE);

  return TRUE;
}


void
launcher_sidebar_show_trash (LauncherSidebar *sidebar,
                             gboolean         show)
{
  LauncherSidebarPrivate *priv;
  ClutterActor *shortcut;
  
  g_return_if_fail (LAUNCHER_IS_SIDEBAR (sidebar));
  priv = sidebar->priv;

  if (show)
  {
    if (CLUTTER_IS_ACTOR (priv->trash))
    {
      priv->shortcuts = g_list_remove (priv->shortcuts, priv->trash);
      clutter_actor_destroy (priv->trash);
    }

    shortcut = priv->trash = launcher_shortcut_new ("gnome-fs-trash-empty", 
                                                    _("Remove favorite"),
                                                    FALSE);
  
    clutter_container_add_actor (CLUTTER_CONTAINER (priv->grid), shortcut);
    clutter_actor_show (shortcut);
    clutter_drag_dest_enable (CLUTTER_DRAG_DEST (priv->trash));

    g_signal_connect (priv->trash, "drop", 
                      G_CALLBACK (on_trashed), NULL);
 
    g_signal_connect (shortcut, "clicked", 
                      G_CALLBACK (on_trash_clicked), NULL);
    priv->shortcuts = g_list_append (priv->shortcuts, shortcut);
  }
  else
  {
    priv->shortcuts = g_list_remove (priv->shortcuts, priv->trash);
    clutter_actor_destroy (priv->trash);
  }
  
  ensure_layout (sidebar);
}

/*
 * FOCUS STUFF
 */
static void
launcher_sidebar_set_focus (ClutterFocusGroup *group, gboolean has_focus)
{
  LauncherSidebarPrivate *priv = LAUNCHER_SIDEBAR (group)->priv;

  if (has_focus)
  {
    priv->focused = priv->shortcuts->data;
    launcher_shortcut_set_active (LAUNCHER_SHORTCUT (priv->focused), TRUE);
  }
  else
    launcher_shortcut_set_active (LAUNCHER_SHORTCUT (priv->focused), FALSE);
}

static gboolean
launcher_sidebar_direction_event (ClutterFocusGroup     *group,
                                 ClutterFocusDirection  dir)
{
  LauncherSidebarPrivate *priv = LAUNCHER_SIDEBAR (group)->priv;
  LauncherConfig *cfg = launcher_config_get_default ();
  LauncherShortcut *new;
  GList *children, *c;
  gint bar_height = cfg->shortcut_height;
  gint current;
  gint next;

  switch (dir)
  {
    case CLUTTER_DIRECTION_RIGHT:
    case CLUTTER_DIRECTION_LEFT:
      return TRUE;
    default:
      ;
  }
  /* Move to the next or previous category, 
   *  if category is first or last, return FALSE
   *  page up and page down takes you to top and bottom
   */
  children = g_list_copy (priv->shortcuts);
  children = g_list_concat (children, g_list_copy (priv->places));
  children = g_list_concat (children, g_list_copy (priv->links));
  current = next = g_list_index (children, priv->focused);

  switch (dir)
  {
    case CLUTTER_DIRECTION_UP:
      next -= 1;
      break;
    case CLUTTER_DIRECTION_DOWN:
      next += 1;
      break;
    case CLUTTER_DIRECTION_PAGE_UP:
      next = 0;
      break;
    case CLUTTER_DIRECTION_PAGE_DOWN:
      next = g_list_length (children) -1;
      break;
    default:
      break;
  }
  if (next < 0) next = 0;
  next = CLAMP (next, 0, g_list_length (children)-1);
  new = g_list_nth_data (children, next);
  priv->focused = CLUTTER_ACTOR (new);
  launcher_shortcut_set_active (new, TRUE);

  for (c = children; c; c= c->next)
  {
    LauncherShortcut *shortcut = c->data;

    if (!LAUNCHER_IS_SHORTCUT (shortcut))
      continue;

    if (shortcut != new)
      launcher_shortcut_set_active (shortcut, FALSE);
  }

  if (TIDY_IS_ADJUSTMENT (priv->adjust))
  {
    gint y, pos, page;

    y = tidy_adjustment_get_value (priv->adjust);
    pos = bar_height * (next);
    page = (N_CATS-2) * bar_height;

    if (pos >= (y + page))
    {
      tidy_adjustment_set_value (priv->adjust, pos);
    }
    else if (pos < y)
    {
      tidy_adjustment_set_value (priv->adjust, pos);
    }
  }

  g_list_free (children);

  return TRUE;
}

static gboolean
launcher_sidebar_action_event (ClutterFocusGroup *group)
{
  LauncherSidebarPrivate *priv = LAUNCHER_SIDEBAR (group)->priv;

  launcher_shortcut_clicked (LAUNCHER_SHORTCUT (priv->focused));

  return TRUE;
}

static gboolean
launcher_sidebar_key_event (ClutterFocusGroup *group, const gchar *string)
{
  g_debug ("String event: %s", string);

  return TRUE;
}                        

static void
clutter_focus_group_iface_init (ClutterFocusGroupIface *iface)
{
  iface->set_focus       = launcher_sidebar_set_focus;
  iface->direction_event = launcher_sidebar_direction_event;
  iface->key_event       = launcher_sidebar_key_event;
  iface->action_event    = launcher_sidebar_action_event;
}

/*
 * /FOCUS STUFF
 */
 

/* GObject stuff */
static void
launcher_sidebar_finalize (GObject *object)
{
  LauncherSidebarPrivate *priv;

  g_return_if_fail (LAUNCHER_IS_SIDEBAR (object));
  priv = LAUNCHER_SIDEBAR (object)->priv;

  g_object_unref (priv->monitor);
  g_object_unref (priv->bookfile_mon);
  g_object_unref (priv->bookfile);

  g_list_free (priv->shortcuts);
  g_list_free (priv->links);
  g_list_free (priv->places);

  g_slist_free (priv->excluded_volumes);

  G_OBJECT_CLASS (launcher_sidebar_parent_class)->finalize (object);
}

static void
launcher_sidebar_class_init (LauncherSidebarClass *klass)
{
  GObjectClass        *obj_class = G_OBJECT_CLASS (klass);
  
  obj_class->finalize = launcher_sidebar_finalize;

  g_type_class_add_private (obj_class, sizeof (LauncherSidebarPrivate));
}

static ClutterActor * 
add_shortcut (LauncherSidebar *sidebar, 
              const gchar *icon_name, 
              const gchar *name,
              const gchar *command)
{
  LauncherSidebarPrivate *priv = sidebar->priv;
  ClutterActor *shortcut;
   
  shortcut = launcher_shortcut_new (icon_name, name, FALSE);
  clutter_container_add_actor (CLUTTER_CONTAINER (priv->grid), shortcut);
  clutter_actor_set_name (shortcut, command);
  clutter_actor_show (shortcut);
  priv->shortcuts = g_list_append (priv->shortcuts, shortcut);
  g_signal_connect (shortcut, "clicked", G_CALLBACK (on_link_clicked), NULL);
  
  return shortcut;
}
      
static void
load_volumes (LauncherSidebar *sidebar)
{
  LauncherSidebarPrivate *priv;
  LauncherConfig *cfg = launcher_config_get_default ();
  ClutterActor *shortcut;
  GList *volumes, *vol;
  gint bar_height = cfg->shortcut_height;
  gchar *home;

  g_return_if_fail (LAUNCHER_IS_SIDEBAR (sidebar));
  priv = sidebar->priv;

  home = g_strdup_printf (NAUTILUS, g_get_home_dir ());
  shortcut = add_shortcut (sidebar, "gnome-fs-home", _("Home"), home);
  g_free (home);
  shortcut = add_shortcut (sidebar, "gnome-fs-network", _("Network"), 
                           "nautilus --no-desktop --browser Network:///");

  volumes = g_volume_monitor_get_volumes (priv->monitor);
  for (vol = volumes; vol; vol = vol->next)
  {
    GVolume *volume;
     
    volume = vol->data;

    if (volume_is_excluded (sidebar, volume))
    {
      g_object_unref (volume);
      continue;
    }
    on_volume_added (priv->monitor, volume, sidebar);
    
    g_object_unref (volume);
  }
  g_list_free (volumes);

  ensure_layout (sidebar);

  shortcut = launcher_shortcut_new ("gtk-quit",
                                    _("Quit..."),
                                    FALSE);
  clutter_container_add_actor (CLUTTER_CONTAINER (sidebar), shortcut);
  clutter_actor_set_position (shortcut, 0, 
                              cfg->win_height - (bar_height)-(PANEL_HEIGHT*2));
  clutter_actor_set_name (shortcut, "gnome-session-save --gui --kill");
  clutter_actor_show (shortcut);
  priv->links = g_list_append (priv->links, shortcut);
  g_signal_connect (shortcut, "clicked", G_CALLBACK (on_link_clicked), NULL);
}

static void
launcher_sidebar_init (LauncherSidebar *sidebar)
{
  LauncherSidebarPrivate *priv;
  LauncherConfig *cfg = launcher_config_get_default ();
  GConfClient *client = gconf_client_get_default ();
  gchar *path;
  
  priv = sidebar->priv = LAUNCHER_SIDEBAR_GET_PRIVATE (sidebar);

  priv->monitor = g_volume_monitor_get ();
  priv->shortcuts = NULL;

  priv->clip = clutter_group_new ();
  clutter_container_add_actor (CLUTTER_CONTAINER (sidebar), priv->clip);
  clutter_actor_set_position (priv->clip, 0, 0);
  clutter_actor_set_clip (priv->clip, 0, 2, cfg->bar_width, 
                          cfg->shortcut_height * (N_CATS-2) +2);
  clutter_actor_show (priv->clip);

  priv->grid = tidy_viewport_new ();
  clutter_container_add_actor (CLUTTER_CONTAINER (priv->clip), priv->grid);
  clutter_actor_set_position (priv->grid, 0, 0);
  clutter_actor_show (priv->grid);

  priv->timeline = clutter_timeline_new_for_duration (SLOW_TIME);
  priv->temp = clutter_effect_template_new (priv->timeline,
                                            clutter_sine_inc_func);

  priv->excluded_volumes = gconf_client_get_list (client, 
                                  "/apps/netbook-launcher/volume_exclude_list",
                                  GCONF_VALUE_STRING,
                                  NULL);

  load_volumes (sidebar);
  load_places (sidebar);

  /* Places monitor */
  path = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);
  priv->bookfile = g_file_new_for_path (path);
  priv->bookfile_mon = g_file_monitor_file (priv->bookfile, 0, NULL, NULL);
  g_signal_connect (priv->bookfile_mon, "changed",
                    G_CALLBACK (on_places_changed), sidebar);
  g_free (path);
  
  g_signal_connect (priv->monitor, "volume-added", 
                    G_CALLBACK (on_volume_added), sidebar);


  clutter_actor_set_reactive (CLUTTER_ACTOR (sidebar), TRUE);
  g_signal_connect (sidebar, "scroll-event",
                    G_CALLBACK (launcher_sidebar_scroll_event), sidebar);
  g_signal_connect (priv->grid, "scroll-event",
                    G_CALLBACK (launcher_sidebar_scroll_event), sidebar);

  g_object_unref (client);
}

ClutterActor *
launcher_sidebar_get_default (void)

{
  static ClutterActor *sidebar = NULL;

  if (!sidebar)
    sidebar = g_object_new (LAUNCHER_TYPE_SIDEBAR, 
                       NULL);

  return sidebar;
}

Generated by  Doxygen 1.6.0   Back to index