Logo Search packages:      
Sourcecode: xarchive version File versions  Download package

myfc_gtk.c

/*
 *  myfc_gtk.c - multiple file chooser
 *  Copyright (C) 2005 Lee Bigelow <ligelowbee@yahoo.com> 
 *
 *  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 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 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"myfc_gtk.h"

void 
myfc_add_foreach_func(gchar *fpath, GtkListStore *myfc_ls)
{
  GtkTreeIter iter;
  gchar *icon = GTK_STOCK_FILE;
  gchar *fdisp;

  fdisp = g_filename_display_name(fpath);
  if ( g_file_test(fpath, G_FILE_TEST_IS_DIR) == TRUE ) 
  {
    icon = GTK_STOCK_DIRECTORY;
  }

  gtk_list_store_append(myfc_ls, &iter);
  gtk_list_store_set(myfc_ls, &iter, COL_ICON, icon, COL_FILE, 
                     fpath, COL_DFILE, fdisp, -1);
  g_free(fdisp);
}

void 
myfc_add_cb(GtkWidget *widget, MyfcData *myfcd)
{
  GSList *selfiles;

  selfiles = gtk_file_chooser_get_filenames(myfcd->fc);
  g_slist_foreach(selfiles, (GFunc) myfc_add_foreach_func, myfcd->ls);
}

void
myfc_onDragDataReceived(GtkWidget *widget,
                   GdkDragContext *context,
                   int x, int y,
                   GtkSelectionData *seldata,
                   guint info, guint time,
                   gpointer userdata)
{
  GtkListStore *myfc_ls;
  gchar **uri_list;
  gchar *hostname;
  gchar *filename;
  gint i;
  
  myfc_ls = GTK_LIST_STORE(userdata);
  uri_list = gtk_selection_data_get_uris(seldata);
  for(i=0; uri_list[i] != NULL; i++)
  {
    filename = g_filename_from_uri(uri_list[i], &hostname, NULL);
    printf("\nhost: %s\npath: %s\n", hostname, filename);
    if ( filename != NULL && g_file_test(filename, G_FILE_TEST_EXISTS) )
       myfc_add_foreach_func(filename, myfc_ls);
    g_free(filename);
  }
  g_strfreev(uri_list);
}
                   
void 
myfc_remove_foreach_func(GtkTreeModel *model, GtkTreePath *path, 
                         GtkTreeIter *iter, GList **rowref_list)
{
  GtkTreeRowReference *rowref;

  rowref = gtk_tree_row_reference_new(model, path);
  *rowref_list = g_list_append(*rowref_list, rowref);
}

void 
myfc_remove_cb(GtkWidget *widget, MyfcData *myfcd)
{
  GtkTreeSelection *sel;
  GtkTreePath *path;
  GtkTreeIter iter;
  GList *rr_list = NULL; /* row ref list of selected rows */
  GList *node;
    
  sel = gtk_tree_view_get_selection(myfcd->tv);
  gtk_tree_selection_selected_foreach(sel, 
                                      (GtkTreeSelectionForeachFunc) 
                                      myfc_remove_foreach_func, 
                                      &rr_list);
    
  for (node = rr_list; node != NULL; node = node->next) 
  {
    path = gtk_tree_row_reference_get_path((GtkTreeRowReference *)
                                           node->data);
    if (path) 
    {
      if ( gtk_tree_model_get_iter(GTK_TREE_MODEL(myfcd->ls), 
                                   &iter, path) ) 
      {
        gtk_list_store_remove(myfcd->ls, &iter);
      }
      gtk_tree_path_free(path);
    }
  }

  g_list_foreach(rr_list, (GFunc) gtk_tree_row_reference_free, NULL);
  g_list_free(rr_list);
}
    
GtkListStore *
make_myfc_ls(void)
{
  GtkListStore *liststore;

  /* store holds (icon, fpath, fdisp) */
  liststore = gtk_list_store_new(3, GTK_TYPE_STRING, GTK_TYPE_STRING, 
                                 GTK_TYPE_STRING); 

  return liststore;
}

GtkWidget *
make_myfc_tree(GtkListStore *myfc_ls)
{
  GtkTreeView *treeview;
  GtkTreeSelection *sel; 
  GtkTreeViewColumn   *tvcol; 
  GtkCellRenderer     *renderer;
  enum { TARGET_URI };
  GtkTargetEntry targetentries[] =
    {
      { "text/uri-list", 0, TARGET_URI },
    };

  treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(myfc_ls)));
  gtk_tree_view_set_rules_hint(treeview, TRUE);

  /* make treeview use multiple selections */
  sel = gtk_tree_view_get_selection(treeview);
  gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
    
  /* create treeview column */
  tvcol = gtk_tree_view_column_new();

  /* filepath icon renderer*/
  renderer = gtk_cell_renderer_pixbuf_new();
  gtk_tree_view_column_pack_start(tvcol, renderer, FALSE);
  gtk_tree_view_column_add_attribute(tvcol, renderer, "stock-id", COL_ICON);

  /* filepath text renderer*/
  renderer = gtk_cell_renderer_text_new();
  gtk_tree_view_column_pack_start(tvcol, renderer, TRUE);
  gtk_tree_view_column_add_attribute(tvcol, renderer, "text", COL_DFILE);

  gtk_tree_view_column_set_title(tvcol, "File and directories to add:");

  /* append column to treeview */
  gtk_tree_view_append_column(treeview, tvcol);

  /* setup drag and drop attributes */
  gtk_drag_dest_set(GTK_WIDGET(treeview), 
                GTK_DEST_DEFAULT_ALL,
                targetentries, 1,
                GDK_ACTION_COPY|GDK_ACTION_MOVE);
  g_signal_connect(GTK_WIDGET(treeview),
               "drag_data_received",
               G_CALLBACK(myfc_onDragDataReceived),
               myfc_ls);

  return GTK_WIDGET(treeview);
}

gboolean
view_popup_menu(GtkWidget *treeview, GdkEventButton *event, MyfcData *myfcd)
{
  GtkWidget *menu, *menuitem;

  if (event->type == GDK_BUTTON_PRESS  &&  event->button == 3)
  {    
    menu = gtk_menu_new();
        
    menuitem = gtk_menu_item_new_with_label("Remove Selected From List");
    g_signal_connect(menuitem, "activate", (GCallback) myfc_remove_cb, myfcd);

    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
    gtk_widget_show_all(menu);
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
                   (event != NULL) ? event->button : 0,
                   gdk_event_get_time((GdkEvent*)event));
    return TRUE;
  }
  return FALSE;
}
    

GtkDialog *
make_myfc(gchar *archive, GtkListStore *myfc_ls)
{
  static MyfcData myfcd;
  GtkDialog *dialog;
  GtkWidget *vpaned, *vbox, *hbox, *label, *button, *image, *scrollw;
  GtkTooltips *button_tips;

  myfcd.ls = myfc_ls;
  button_tips = gtk_tooltips_new();

  /* make general dialog box */
  dialog = GTK_DIALOG( gtk_dialog_new_with_buttons(
                                                   "Select Files or Directories To Add", NULL,
                                                   GTK_DIALOG_MODAL,
                                                   GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                                   GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
                                                   NULL) );
  gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT,
                                          GTK_RESPONSE_CANCEL, -1);
  
  /* pack panes into dialog vbox */
  vpaned = gtk_vpaned_new();
  gtk_container_add(GTK_CONTAINER(dialog->vbox), vpaned);
  gtk_widget_show(vpaned);

  /* pack file chooser into top pane */
  myfcd.fc = GTK_FILE_CHOOSER(
                              gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN) );
  gtk_paned_pack1(GTK_PANED(vpaned), GTK_WIDGET(myfcd.fc), TRUE, TRUE);
  gtk_widget_show(GTK_WIDGET(myfcd.fc));

  gtk_widget_set_size_request(GTK_WIDGET(myfcd.fc), 450, 200);
  gtk_file_chooser_set_select_multiple(myfcd.fc, TRUE);

  /* pack vbox of treeview into bottom pane */
  vbox = gtk_vbox_new(FALSE, 0);
  gtk_widget_set_size_request(vbox, 450, 180);
  gtk_widget_show (vbox);
  gtk_paned_pack2(GTK_PANED(vpaned), GTK_WIDGET(vbox), TRUE, TRUE);

  /* hbox for buttons goes in top of vbox */
  hbox = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE,FALSE, 0);

  /* label packs into start of hbox */
  label = gtk_label_new(archive);
  gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 5);
  gtk_widget_show(label);
   
  gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_START);
    
  /* remove button packs into end of hbox */
  button = gtk_button_new_with_mnemonic("Remove _From list");
  gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
  gtk_widget_show(button);
  g_signal_connect(G_OBJECT(button), "clicked", 
                   G_CALLBACK(myfc_remove_cb), &myfcd);
  image = gtk_image_new_from_stock(GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
  gtk_button_set_image(GTK_BUTTON(button), image);
  gtk_tooltips_set_tip(button_tips, button, 
                       "(ALT-F) Remove selected files from the \"add to archive\" list below.", NULL);

  /* add button packs into end of hbox */
  button = gtk_button_new_with_mnemonic("Add _To list");
  gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
  gtk_widget_show(button);
  g_signal_connect(G_OBJECT(button), "clicked", 
                   G_CALLBACK(myfc_add_cb), &myfcd);
  image = gtk_image_new_from_stock(GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_BUTTON);
  gtk_button_set_image(GTK_BUTTON(button), image);
  gtk_tooltips_set_tip(button_tips, button, 
                       "(ALT-T) Add selected files from the \"file chooser\" above to the \"add to archive\" list below.", NULL);

    
  /* next scroll window packs in vbox */
  scrollw = gtk_scrolled_window_new(NULL, NULL);
  gtk_box_pack_start(GTK_BOX(vbox), scrollw, TRUE, TRUE, 0);
  gtk_widget_show(scrollw);

  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollw),
                                 GTK_POLICY_AUTOMATIC,
                                 GTK_POLICY_AUTOMATIC);

  /* finally the treeview packs into the scrollw */
  myfcd.tv = GTK_TREE_VIEW(make_myfc_tree(myfc_ls)); 
  gtk_container_add(GTK_CONTAINER(scrollw), GTK_WIDGET(myfcd.tv));
  gtk_widget_show(GTK_WIDGET(myfcd.tv));
  g_signal_connect(GTK_WIDGET(myfcd.tv), "button_press_event", (GCallback) view_popup_menu, &myfcd);
    
  return dialog;
}

Generated by  Doxygen 1.6.0   Back to index