Logo Search packages:      
Sourcecode: kazehakase version File versions

kz-download-box.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2003 Hiroyuki Ikezoe
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

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

#include "kz-download-box.h"
#include "kz-actions-download.h"
#include "gobject-utils.h"
#include "gtk-utils.h"

static void kz_download_box_class_init (KzDownloadBoxClass *klass);
static void kz_download_box_init       (KzDownloadBox      *dlbox);
static void kz_download_box_dispose    (GObject            *object);

static void kz_download_box_drag_data_received (GtkWidget        *widget,
                                    GdkDragContext   *context,
                                    gint              x,
                                    gint              y,
                                    GtkSelectionData *data,
                                    guint             info,
                                    guint             time);

static void cb_add_item       (KzDownloaderGroup *dlgrp,
                         KzDownloader      *dl,
                         KzDownloadBox     *dlbox);
static void cb_remove_item    (KzDownloaderGroup *dlgrp,
                         KzDownloader      *dl,
                         KzDownloadBox     *dlbox);
static void cb_progress_item  (KzDownloaderGroup *dlgrp,
                         KzDownloader      *dl,
                         KzDownloadBox     *dlbox);

static void remove_icon       (KzDownloaderIcon *icon);

static GtkStatusbarClass *parent_class = NULL;

enum {
      TARGET_NETSCAPE_URL,
      TARGET_TEXT_URI_LIST
};

static GtkTargetEntry url_drag_types [] = 
{
        { "_NETSCAPE_URL",   0, TARGET_NETSCAPE_URL},
      { "text/uri-list",   0, TARGET_TEXT_URI_LIST}
};

static guint n_url_drag_types = G_N_ELEMENTS (url_drag_types);

KZ_OBJECT_GET_TYPE(kz_download_box, "KzDownloadBox", KzDownloadBox,
               kz_download_box_class_init, kz_download_box_init,
               GTK_TYPE_STATUSBAR)

static void
kz_download_box_class_init (KzDownloadBoxClass *klass)
{
      GObjectClass *gobject_class;
      GtkWidgetClass *widget_class;

      parent_class = g_type_class_peek_parent (klass);

      gobject_class = (GObjectClass *) klass;
      widget_class  = (GtkWidgetClass *) klass;

      /* GtkObject signals */
      gobject_class->dispose = kz_download_box_dispose;

      /* GtkWidget signales */
      /* widget_class->drag_motion          = kz_download_box_drag_motion; */
      /* widget_class->drag_data_get        = kz_download_box_drag_data_get; */
      widget_class->drag_data_received   = kz_download_box_drag_data_received;
}

static void
kz_download_box_init (KzDownloadBox *dlbox)
{
      /* widgets */
      dlbox->kz = NULL;
      
      dlbox->dlgrp     = NULL;
      dlbox->icon_list = NULL;

      gtk_drag_dest_set(GTK_WIDGET(dlbox), 
                    GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_MOTION | 
                    GTK_DEST_DEFAULT_DROP,
                          url_drag_types,n_url_drag_types,
                    GDK_ACTION_LINK);
}


GtkWidget *
kz_download_box_new (KzWindow *kz)
{
      KzDownloadBox *dlbox;

      dlbox = g_object_new(KZ_TYPE_DOWNLOAD_BOX, NULL);

      dlbox->kz = kz;
      
      dlbox->dlgrp = kz_downloader_group_get_instance();

      g_signal_connect(dlbox->dlgrp, "add",
                   G_CALLBACK(cb_add_item), dlbox);
      g_signal_connect(dlbox->dlgrp, "remove",
                   G_CALLBACK(cb_remove_item), dlbox);      
      g_signal_connect(dlbox->dlgrp, "progress",
                   G_CALLBACK(cb_progress_item), dlbox);    

      return GTK_WIDGET(dlbox);
}


static void
kz_download_box_dispose (GObject *object)
{
      KzDownloadBox *dlbox = KZ_DOWNLOAD_BOX(object);

      if (dlbox->icon_list)
      {
            g_slist_free(dlbox->icon_list);
            dlbox->icon_list = NULL;
      }
      
      if (dlbox->dlgrp)
      {
            g_signal_handlers_disconnect_by_func(dlbox->dlgrp,
                                         G_CALLBACK(cb_add_item),
                                         dlbox);
            g_signal_handlers_disconnect_by_func(dlbox->dlgrp,
                                         G_CALLBACK(cb_remove_item),
                                         dlbox);
            g_signal_handlers_disconnect_by_func(dlbox->dlgrp,
                                         G_CALLBACK(cb_progress_item),
                                         dlbox);
            g_object_unref(dlbox->dlgrp);
            dlbox->dlgrp = NULL;
      }

      if (G_OBJECT_CLASS (parent_class)->dispose)
            (*G_OBJECT_CLASS (parent_class)->dispose) (object);
}


static void
kz_download_box_drag_data_received (GtkWidget *widget,
                            GdkDragContext *context,
                            gint x, gint y,
                            GtkSelectionData *data,
                            guint info,
                            guint time)
{
      KzDownloadBox *dlbox;
      gchar **strings, *basename;

      dlbox = KZ_DOWNLOAD_BOX(widget);

      switch (info)
      {
       case TARGET_NETSCAPE_URL:
       case TARGET_TEXT_URI_LIST:
            if (data->length < 0) return;

            strings = g_strsplit(data->data, "\n", 2);

            basename = g_path_get_basename(strings[0]);
            if (g_file_test(basename, G_FILE_TEST_EXISTS))
            {
                  gboolean ret;
                  ret = gtkutil_confirm_file_replace(GTK_WINDOW(dlbox->kz),
                                             basename);
                  if (!ret)
                  {
                        kz_actions_download_open_save_dialog(GTK_WINDOW(dlbox->kz),
                                                     strings[0], FALSE);
                        g_strfreev(strings);
                        g_free(basename);
                        break;
                  }
            }
            
            kz_downloader_group_add_item(dlbox->dlgrp, strings[0]);
            
            g_strfreev(strings);
            g_free(basename);
            gtk_drag_finish(context, TRUE, FALSE, time);
            return;
            break;
       default:
            break;
      }
      gtk_drag_finish(context, FALSE, FALSE, time);
}


static void
cb_download_icon_destroy (GtkWidget *widget, GtkWidget *menu)
{
      gtk_widget_destroy (menu);
}


static void 
cb_cancel_menu_activate (GtkWidget *widget, KzDownloaderIcon *icon)
{
      kz_downloader_cancel (icon->dl);
}


static void
cb_icon_clicked (GtkWidget *event_box,
             GdkEventButton *event,
             KzDownloaderIcon *icon)
{
      GtkWidget *menu, *menuitem;

      switch (event->button) {
      case 1:
            break;
      case 2:
            break;
      case 3:
            menu = gtk_menu_new();
            g_signal_connect(G_OBJECT(icon->event_box), "destroy",
                         G_CALLBACK(cb_download_icon_destroy), menu);
            menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_CANCEL, NULL);
            g_signal_connect(G_OBJECT(menuitem), "activate",
                         G_CALLBACK(cb_cancel_menu_activate), icon);
            gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem);
            gtk_widget_show (menuitem);
            gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
                        event->button, event->time);
            break;
      default:
            break;
      }
}


static void
cb_add_item (KzDownloaderGroup *dlgrp,
           KzDownloader      *dl,
           KzDownloadBox     *dlbox)
{
      KzDownloaderIcon *icon;
      gint width, height;
      GdkPixbuf *orig_pixbuf, *transparent_pixbuf;
      GtkIconSet *icon_set;

      icon = g_new0(KzDownloaderIcon, 1);
      icon->dl    = g_object_ref(dl);

      icon->fraction = 0;

      /* add an icon in download box */
      icon->event_box   = gtk_event_box_new();
      icon->image = gtk_image_new();
      icon->tips  = gtk_tooltips_new();
      dlbox->icon_list = g_slist_append(dlbox->icon_list, icon);

      /* create semitransparent icon image */
      gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
      icon_set = gtk_style_lookup_icon_set (GTK_WIDGET(dlbox)->style,
                                    GTK_STOCK_SAVE);

      if (icon_set != NULL)
      {
            orig_pixbuf = gtk_icon_set_render_icon (
                        icon_set,
                        icon->image->style,
                        gtk_widget_get_direction (icon->image),
                        GTK_WIDGET_STATE (icon->image),
                        GTK_ICON_SIZE_MENU,
                        icon->image,
                        "download icon");
      }
      else
      {
            orig_pixbuf = gtk_widget_render_icon(icon->image,
                                         GTK_STOCK_SAVE,
                                         GTK_ICON_SIZE_MENU,
                                         NULL);
      }
      transparent_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
                                  TRUE,
                                  8,
                                  width,
                                  height);
      gdk_pixbuf_fill(transparent_pixbuf, 0);
      gdk_pixbuf_composite(orig_pixbuf,
                       transparent_pixbuf,
                       0, 0,
                       width, height,
                       0, 0,
                       1, 1,
                       GDK_INTERP_NEAREST,
                       64);
            
      gtk_image_set_from_pixbuf(GTK_IMAGE(icon->image), transparent_pixbuf);
      g_object_unref(orig_pixbuf);
      g_object_unref(transparent_pixbuf);

      gtk_container_add(GTK_CONTAINER(icon->event_box), icon->image);
      gtk_widget_show(icon->image);
      gtk_widget_show(icon->event_box);
      gtk_box_pack_start(GTK_BOX(dlbox), icon->event_box, FALSE, FALSE, 0);

      g_signal_connect(icon->event_box, "button_press_event",
                   G_CALLBACK(cb_icon_clicked), icon);

}


static void
cb_remove_item (KzDownloaderGroup *dlgrp,
            KzDownloader      *dl,
            KzDownloadBox     *dlbox)
{
      GSList *list;

      g_return_if_fail(KZ_IS_DOWNLOADER(dl));
      g_return_if_fail(KZ_IS_DOWNLOAD_BOX(dlbox));

      for (list = dlbox->icon_list; list; list = g_slist_next(list))
      {
            KzDownloaderIcon *icon = list->data;
            if (icon->dl == dl)
            {
                  dlbox->icon_list = g_slist_remove(dlbox->icon_list, icon);
                  remove_icon(icon);
                  g_object_unref(icon->dl);
                  icon->dl = NULL;
                  g_free(icon);
                  break;
            }
      }     

}


static void
cb_progress_item (KzDownloaderGroup *dlgrp,
              KzDownloader      *dl,
              KzDownloadBox     *dlbox)
{
      GSList *list;
      gchar *percent_str;
      gint percent;
      KzDownloaderIcon *icon = NULL;
      gint width, height, fraction;

      g_return_if_fail(KZ_IS_DOWNLOADER(dl));
      g_return_if_fail(KZ_IS_DOWNLOADER_GROUP(dlgrp));
      g_return_if_fail(KZ_IS_DOWNLOAD_BOX(dlbox));

      /* find icon */
      for (list = dlbox->icon_list; list; list = g_slist_next(list))
      {
            if (list->data && ((KzDownloaderIcon *) list->data)->dl == dl)
            {
                  icon = list->data;
                  break;
            }
      }
      if (!icon) return;

      /* set status */
      percent = kz_downloader_get_percent(dl);
      gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);

      fraction = percent / (100 / height);
      if (fraction > icon->fraction && icon->fraction <= height)
      {
            GdkPixbuf *orig_pixbuf, *pixbuf;
            gchar *direction;
            gint x = 0, y = 0;

            icon->fraction = fraction;
            direction = KZ_CONF_GET_STR("Download",
                                  "icon_fade_in_direction");
            orig_pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(icon->image));
            pixbuf = gtk_widget_render_icon(icon->image,
                                    GTK_STOCK_SAVE, 
                                    GTK_ICON_SIZE_MENU,
                                    NULL);
            if (direction)
            {
                  if (!strcasecmp(direction, "down"))
                  {
                        height = height * percent / 100;
                  }
                  else if (!strcasecmp(direction, "left"))
                  {
                        width = width * percent / 100;
                  }
                  else if (!strcasecmp(direction, "right"))
                  {
                        x = width - width * percent / 100;
                        width = width * percent / 100;
                  }
                  else if (!strcasecmp(direction, "up"))
                  {
                        y = height - height * percent / 100;
                        height = height * percent / 100;
                  }
                  else
                  {
                        g_warning(_("KzDownloadBox: "
                                  "unknown the direction of icon fading in!: %s"),
                                direction);
                        y = height - height * percent / 100;
                        height = height * percent / 100;
                  }
            }
            else /* upward by default */
            {
                  y = height - height * percent / 100;
                  height = height * percent / 100;
            }
            gdk_pixbuf_composite(pixbuf,
                             orig_pixbuf,
                             x, y,
                             width, height,
                             0, 0,
                             1, 1,
                             GDK_INTERP_NEAREST,
                             255);
            gtk_image_set_from_pixbuf(GTK_IMAGE(icon->image),
                                orig_pixbuf);
            g_object_unref(pixbuf);
            if(direction)
                  g_free(direction);
      }
      percent_str = g_strdup_printf("%s:%02d%%",
                              dl->filename,
                              percent);
      gtk_tooltips_set_tip(icon->tips, icon->event_box,
                       percent_str,
                       NULL);
      g_free(percent_str);
}


static void
remove_icon (KzDownloaderIcon *icon)
{
      gtk_widget_destroy(icon->event_box);
}

Generated by  Doxygen 1.6.0   Back to index