Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20064543
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
42 KB
Subscribers
None
View Options
diff --git a/src/dndtest.c b/src/dndtest.c
index a88a808..51aeded 100644
--- a/src/dndtest.c
+++ b/src/dndtest.c
@@ -1,401 +1,407 @@
/* TestDnD - main.c : Simple tutorial for GTK+ Drag-N-Drop
* Copyright (C) 2005 Ryan McDougall.
*
* 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 Library 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 <gtk/gtk.h>
#include <string.h>
/******************************************************************************/
#define _BYTE 8
#define _WORD 16
#define _DWORD 32
/******************************************************************************/
/* Define a list of data types called "targets" that a destination widget will
* accept. The string type is arbitrary, and negotiated between DnD widgets by
* the developer. An enum or GQuark can serve as the integer target id. */
enum {
TARGET_INT32,
TARGET_STRING,
TARGET_URIS,
TARGET_ROOTWIN
};
/* datatype (string), restrictions on DnD (GtkTargetFlags), datatype (int) */
static GtkTargetEntry target_list[] = {
{ "INTEGER", 0, TARGET_INT32 },
{ "STRING", 0, TARGET_STRING },
{ "text/plain", 0, TARGET_STRING },
{ "text/uri-list", 0, TARGET_URIS },
{ "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
};
static guint n_targets = G_N_ELEMENTS (target_list);
/******************************************************************************/
/* Signal receivable by destination */
/* Emitted when the data has been received from the source. It should check
* the GtkSelectionData sent by the source, and do something with it. Finally
* it needs to finish the operation by calling gtk_drag_finish, which will emit
* the "data-delete" signal if told to. */
static void
drag_data_received_handl
(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
GtkSelectionData *selection_data, guint target_type, guint tim,
gpointer data)
{
glong *_idata;
gchar *_sdata;
gboolean dnd_success = FALSE;
gboolean delete_selection_data = FALSE;
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_data_received_handl\n", name);
/* Deal with what we are given from source */
- if((selection_data != NULL) && (selection_data-> length >= 0))
+ if((selection_data != NULL) && (gtk_selection_data_get_length(selection_data) >= 0))
{
- if (context-> action == GDK_ACTION_ASK)
+ GdkDragAction drag_action = gdk_drag_context_get_suggested_action(context);
+
+ if (drag_action == GDK_ACTION_ASK)
{
/* Ask the user to move or copy, then set the context action. */
}
- if (context-> action == GDK_ACTION_MOVE)
+ if (drag_action == GDK_ACTION_MOVE)
delete_selection_data = TRUE;
/* Check that we got the format we can use */
g_print (" Receiving ");
switch (target_type)
{
case TARGET_INT32:
- _idata = (glong*)selection_data-> data;
+ _idata = (glong*)gtk_selection_data_get_data(selection_data);
g_print ("integer: %ld", *_idata);
dnd_success = TRUE;
break;
case TARGET_STRING:
- _sdata = (gchar*)selection_data-> data;
+ _sdata = (gchar*)gtk_selection_data_get_data(selection_data);
g_print ("string: %s", _sdata);
dnd_success = TRUE;
break;
case TARGET_URIS:
- _sdata = (gchar*)selection_data-> data;
+ _sdata = (gchar*)gtk_selection_data_get_data(selection_data);
g_print ("uris: %s", _sdata);
dnd_success = TRUE;
break;
default:
g_print ("nothing good");
}
g_print (".\n");
}
if (dnd_success == FALSE)
{
g_print ("DnD data transfer failed!\n");
}
gtk_drag_finish (context, dnd_success, delete_selection_data, tim);
}
/* Emitted when a drag is over the destination */
static gboolean
drag_motion_handl
(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint t,
gpointer user_data)
{
// Fancy stuff here. This signal spams the console something horrible.
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_motion_handl\n", name);
return FALSE;
}
/* Emitted when a drag leaves the destination */
static void
drag_leave_handl
(GtkWidget *widget, GdkDragContext *context, guint tim, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_leave_handl\n", name);
}
/* Emitted when the user releases (drops) the selection. It should check that
* the drop is over a valid part of the widget (if its a complex widget), and
* itself to return true if the operation should continue. Next choose the
* target type it wishes to ask the source for. Finally call gtk_drag_get_data
* which will emit "drag-data-get" on the source. */
static gboolean
drag_drop_handl
(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint tim,
gpointer user_data)
{
gboolean is_valid_drop_site;
GdkAtom target_type;
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_drop_handl\n", name);
/* Check to see if (x,y) is a valid drop site within widget */
is_valid_drop_site = TRUE;
+ GList *targets = gdk_drag_context_list_targets(context);
+
/* If the source offers a target */
- if (context-> targets)
+ if (targets)
{
/* Choose the best target type */
target_type = GDK_POINTER_TO_ATOM
- (g_list_nth_data (context-> targets, TARGET_INT32));
+ (g_list_nth_data (targets, TARGET_INT32));
/* Request the data from the source. */
gtk_drag_get_data
(
widget, /* will receive 'drag-data-received' signal */
context, /* represents the current state of the DnD */
target_type, /* the target type we want */
tim /* time stamp */
);
}
/* No target offered by source => error */
else
{
is_valid_drop_site = FALSE;
}
return is_valid_drop_site;
}
/******************************************************************************/
/* Signals receivable by source */
/* Emitted after "drag-data-received" is handled, and gtk_drag_finish is called
* with the "delete" parameter set to TRUE (when DnD is GDK_ACTION_MOVE). */
static void
drag_data_delete_handl
(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
{
// We aren't moving or deleting anything here
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_data_delete_handl\n", name);
}
/* Emitted when the destination requests data from the source via
* gtk_drag_get_data. It should attempt to provide its data in the form
* requested in the target_type passed to it from the destination. If it cannot,
* it should default to a "safe" type such as a string or text, even if only to
* print an error. Then use gtk_selection_data_set to put the source data into
* the allocated selection_data object, which will then be passed to the
* destination. This will cause "drag-data-received" to be emitted on the
* destination. GdkSelectionData is based on X's selection mechanism which,
* via X properties, is only capable of storing data in blocks of 8, 16, or
* 32 bit units. */
static void
drag_data_get_handl
(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data,
guint target_type, guint tim, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
const gchar *string_data = "This is data from the source.";
const glong integer_data = 42;
g_print ("%s: drag_data_get_handl\n", name);
g_assert (selection_data != NULL);
+ GdkAtom target = gtk_selection_data_get_target(selection_data);
+
g_print (" Sending ");
switch (target_type)
{
/* case TARGET_SOME_OBJECT:
* Serialize the object and send as a string of bytes.
* Pixbufs, (UTF-8) text, and URIs have their own convenience
* setter functions */
case TARGET_INT32:
g_print ("integer: %ld", integer_data);
gtk_selection_data_set
(
selection_data, /* Allocated GdkSelectionData object */
- selection_data-> target,/* target type */
+ target,/* target type */
_DWORD, /* number of bits per 'unit' */
(guchar*) &integer_data,/* pointer to data to be sent */
sizeof (integer_data) /* length of data in units */
);
break;
case TARGET_STRING:
g_print ("string: %s", string_data);
gtk_selection_data_set
(
selection_data,
- selection_data-> target,
+ target,
_BYTE,
(guchar*) string_data,
strlen (string_data)
);
break;
case TARGET_URIS:
g_print ("uris: %s", string_data);
gtk_selection_data_set
(
selection_data,
- selection_data-> target,
+ target,
_BYTE,
(guchar*) string_data,
strlen (string_data)
);
break;
case TARGET_ROOTWIN:
g_print ("Dropped on the root window!\n");
break;
default:
/* Default to some a safe target instead of fail. */
g_assert_not_reached ();
}
g_print (".\n");
}
/* Emitted when DnD begins. This is often used to present custom graphics. */
static void
drag_begin_handl
(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_begin_handl\n", name);
}
/* Emitted when DnD ends. This is used to clean up any leftover data. */
static void
drag_end_handl
(GtkWidget *widget, GdkDragContext *context, gpointer user_data)
{
const gchar *name = gtk_widget_get_name (widget);
g_print ("%s: drag_end_handl\n", name);
}
/******************************************************************************/
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *hbox;
GtkWidget *coin_source;
GtkWidget *well_dest;
GtkWidget *directions_label;
guint win_xsize = 450;
guint win_ysize = 50;
guint spacing = 5;
/* Always start GTK+ first! */
gtk_init (&argc, &argv);
/* Create the widgets */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
hbox = gtk_hbox_new (FALSE, spacing);
coin_source = gtk_button_new_with_label ("[coins]");
well_dest = gtk_label_new ("[a well]");
directions_label = gtk_label_new ("drag a coin and drop it in the well");
/* Pack the widgets */
gtk_container_add (GTK_CONTAINER (window), hbox);
gtk_container_add (GTK_CONTAINER (hbox), coin_source);
gtk_container_add (GTK_CONTAINER (hbox), directions_label);
gtk_container_add (GTK_CONTAINER (hbox), well_dest);
/* Make the window big enough for some DnD action */
gtk_window_set_default_size (GTK_WINDOW(window), win_xsize, win_ysize);
/* Make the "well label" a DnD destination. */
gtk_drag_dest_set
(
well_dest, /* widget that will accept a drop */
GTK_DEST_DEFAULT_MOTION /* default actions for dest on DnD */
| GTK_DEST_DEFAULT_HIGHLIGHT,
target_list, /* lists of target to support */
n_targets, /* size of list */
GDK_ACTION_COPY /* what to do with data after dropped */
);
/* Make the "coin button" a DnD source. */
/* Why doesn't GtkLabel work here? */
gtk_drag_source_set
(
coin_source, /* widget will be drag-able */
GDK_BUTTON1_MASK, /* modifier that will start a drag */
target_list, /* lists of target to support */
n_targets, /* size of list */
GDK_ACTION_COPY /* what to do with data after dropped */
);
/* Connect the signals */
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
/* All possible destination signals */
g_signal_connect (well_dest, "drag-data-received",
G_CALLBACK(drag_data_received_handl), NULL);
g_signal_connect (well_dest, "drag-leave",
G_CALLBACK (drag_leave_handl), NULL);
g_signal_connect (well_dest, "drag-motion",
G_CALLBACK (drag_motion_handl), NULL);
g_signal_connect (well_dest, "drag-drop",
G_CALLBACK (drag_drop_handl), NULL);
/* All possible source signals */
g_signal_connect (coin_source, "drag-data-get",
G_CALLBACK (drag_data_get_handl), NULL);
g_signal_connect (coin_source, "drag-data-delete",
G_CALLBACK (drag_data_delete_handl), NULL);
g_signal_connect (coin_source, "drag-begin",
G_CALLBACK (drag_begin_handl), NULL);
g_signal_connect (coin_source, "drag-end",
G_CALLBACK (drag_end_handl), NULL);
/* Show the widgets */
gtk_widget_show_all (window);
/* Start the even loop */
gtk_main ();
return 0;
}
diff --git a/src/fileman.c b/src/fileman.c
index cb0b67f..e16bde3 100644
--- a/src/fileman.c
+++ b/src/fileman.c
@@ -1,918 +1,925 @@
/* fileman.c - The GNU Privacy Assistant
Copyright (C) 2000, 2001 G-N-U GmbH.
Copyright (C) 2007, 2008 g10 Code GmbH
This file is part of GPA.
GPA 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 3 of the License, or
(at your option) any later version.
GPA 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/>. */
/* The file encryption/decryption/sign window. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#include <gdk/gdkkeysyms.h>
#include <glib.h>
#include <gtk/gtk.h>
#include "gpa.h"
#include "gtktools.h"
#include "gpawidgets.h"
#include "siglist.h"
#include "helpmenu.h"
#include "icons.h"
#include "fileman.h"
#include "gpafiledecryptop.h"
#include "gpafileencryptop.h"
#include "gpafilesignop.h"
#include "gpafileverifyop.h"
#if ! GTK_CHECK_VERSION (2, 10, 0)
#define GTK_STOCK_SELECT_ALL "gtk-select-all"
#endif
/* Object and class definition. */
struct _GpaFileManager
{
GtkWindow parent;
GtkWidget *window;
GtkWidget *list_files;
GList *selection_sensitive_actions;
};
struct _GpaFileManagerClass
{
GtkWindowClass parent_class;
};
/* There is only one instance of the file manage class. Use a global
variable to keep track of it. */
static GpaFileManager *instance;
/* We also need to save the parent class. */
static GObjectClass *parent_class;
/* Definition of the sensitivity function type. */
typedef gboolean (*sensitivity_func_t)(gpointer);
/* Constants to define the file list. */
enum
{
FILE_NAME_COLUMN,
FILE_N_COLUMNS
};
#define DND_TARGET_URI_LIST 1
/* Drag and drop target list. */
static GtkTargetEntry dnd_target_list[] =
{
{ "text/uri-list", 0, DND_TARGET_URI_LIST }
};
/* Local prototypes */
static GObject *gpa_file_manager_constructor
(GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties);
/*
* GtkWidget boilerplate.
*/
static void
gpa_file_manager_finalize (GObject *object)
{
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gpa_file_manager_init (GpaFileManager *fileman)
{
fileman->selection_sensitive_actions = NULL;
}
static void
gpa_file_manager_class_init (GpaFileManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->constructor = gpa_file_manager_constructor;
object_class->finalize = gpa_file_manager_finalize;
}
GType
gpa_file_manager_get_type (void)
{
static GType fileman_type = 0;
if (!fileman_type)
{
static const GTypeInfo fileman_info =
{
sizeof (GpaFileManagerClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gpa_file_manager_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GpaFileManager),
0, /* n_preallocs */
(GInstanceInitFunc) gpa_file_manager_init,
};
fileman_type = g_type_register_static (GTK_TYPE_WINDOW,
"GpaFileManager",
&fileman_info, 0);
}
return fileman_type;
}
/*
* File manager methods
*/
/* Return the currently selected files as a new list of filenames
* structs. The list and the texts must be freed by the caller.
*/
static GList *
get_selected_files (GtkWidget *list)
{
GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
GList *selection = gtk_tree_selection_get_selected_rows (sel, &model);
GList *files = NULL;
while (selection)
{
gpa_file_item_t file_item;
gchar *filename;
GtkTreeIter iter;
gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) selection->data);
gtk_tree_model_get (model, &iter, FILE_NAME_COLUMN, &filename, -1);
file_item = g_malloc0 (sizeof (*file_item));
file_item->filename_in = filename;
files = g_list_append (files, file_item);
selection = g_list_next (selection);
}
/* Free the selection */
g_list_foreach (selection, (GFunc) gtk_tree_path_free, NULL);
g_list_free (selection);
return files;
}
/* Add file FILENAME to the file list of FILEMAN and select it */
static gboolean
add_file (GpaFileManager *fileman, const gchar *filename)
{
GtkListStore *store;
GtkTreeIter iter;
GtkTreePath *path;
GtkTreeSelection *sel;
gchar *filename_utf8;
/* The tree contains filenames in the UTF-8 encoding. */
filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
/* Try to convert from the current locale as fallback. This is important
for windows where g_filename_to_utf8 does not take locale into account
because the filedialogs already convert to utf8. */
if (!filename_utf8)
{
filename_utf8 = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
}
/* Last fallback is guranteed to never be NULL so in doubt we can still fail
later showing a filename that can't be found to the user etc.*/
if (!filename_utf8)
{
filename_utf8 = g_filename_display_name (filename);
}
store = GTK_LIST_STORE (gtk_tree_view_get_model
(GTK_TREE_VIEW (fileman->list_files)));
/* Check for duplicates. */
path = gtk_tree_path_new_first ();
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
do
{
gchar *tmp;
gboolean exists;
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, FILE_NAME_COLUMN,
&tmp, -1);
exists = g_str_equal (filename_utf8, tmp);
g_free (tmp);
if (exists)
{
g_free (filename_utf8);
gtk_tree_path_free (path);
return FALSE; /* This file is already in our list. */
}
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_path_free (path);
/* Append it to our list. */
gtk_list_store_append (store, &iter);
/* FIXME: Add the file status when/if gpgme supports it */
gtk_list_store_set (store, &iter, FILE_NAME_COLUMN, filename_utf8, -1);
/* Select the row */
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (fileman->list_files));
gtk_tree_selection_select_iter (sel, &iter);
return TRUE;
}
/* Add a file created by an operation to the list */
static void
file_created_cb (GpaFileOperation *op, gpa_file_item_t item, gpointer data)
{
GpaFileManager *fileman = data;
add_file (fileman, item->filename_out);
}
/* Do whatever is required with a file operation, to ensure proper clean up */
static void
register_operation (GpaFileManager *fileman, GpaFileOperation *op)
{
g_signal_connect (G_OBJECT (op), "created_file",
G_CALLBACK (file_created_cb), fileman);
g_signal_connect (G_OBJECT (op), "completed",
G_CALLBACK (g_object_unref), NULL);
}
/* Management of the selection sensitive actions. */
/* Return true if a selection is active. */
static gboolean
has_selection (gpointer param)
{
GpaFileManager *fileman = param;
GtkTreeSelection *sel;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (fileman->list_files));
return (gtk_tree_selection_count_selected_rows (sel) > 0);
}
/* Add WIDGET to the list of sensitive actions of FILEMAN. */
static void
add_selection_sensitive_action (GpaFileManager *fileman,
GtkAction *action,
sensitivity_func_t callback)
{
g_object_set_data (G_OBJECT (action), "gpa_sensitivity", callback);
fileman->selection_sensitive_actions
= g_list_append (fileman->selection_sensitive_actions, action);
}
/* Update the sensitivity of the widget DATA and pass PARAM through to
the sensitivity callback. Usable as an iterator function in
g_list_foreach. */
static void
update_selection_sensitive_action (gpointer data, gpointer param)
{
sensitivity_func_t func;
func = g_object_get_data (G_OBJECT (data), "gpa_sensitivity");
gtk_action_set_sensitive (GTK_ACTION (data), func (param));
}
/* Call update_selection_sensitive_action for all widgets in the list
of sensitive actions and pass FILEMAN through as the user data
parameter. */
static void
update_selection_sensitive_actions (GpaFileManager *fileman)
{
g_list_foreach (fileman->selection_sensitive_actions,
update_selection_sensitive_action,
(gpointer) fileman);
}
/* Actions as called by the menu items. */
static GSList *
get_load_file_name (GtkWidget *parent, const gchar *title,
const gchar *directory)
{
static GtkWidget *dialog;
GtkResponseType response;
GSList *filenames = NULL;
if (! dialog)
{
dialog = gtk_file_chooser_dialog_new
(title, GTK_WINDOW (parent), GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
}
if (directory)
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), directory);
gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (dialog));
/* Run the dialog until there is a valid response. */
response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response == GTK_RESPONSE_OK)
filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog));
gtk_widget_hide (dialog);
return filenames;
}
/* Handle menu item "File/Open". */
void
open_file_one (gpointer data, gpointer user_data)
{
GpaFileManager *fileman = user_data;
gchar *filename = (gchar *) data;
/* FIXME: We are ignoring errors here. */
add_file (fileman, filename);
g_free (filename);
}
static void
file_open (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
GSList *filenames;
filenames = get_load_file_name (GTK_WIDGET (fileman), _("Open File"), NULL);
if (! filenames)
return;
g_slist_foreach (filenames, open_file_one, fileman);
g_slist_free (filenames);
}
/* Handle menu item "File/Clear". */
static void
file_clear (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model
(GTK_TREE_VIEW (fileman->list_files)));
gtk_list_store_clear (store);
}
/* Handle menu item "File/Verify". */
static void
file_verify (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
GList *files;
GpaFileVerifyOperation *op;
files = get_selected_files (fileman->list_files);
if (!files)
return;
op = gpa_file_verify_operation_new (GTK_WIDGET (fileman), files);
register_operation (fileman, GPA_FILE_OPERATION (op));
}
/* Handle menu item "File/Sign". */
static void
file_sign (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
GList * files;
GpaFileSignOperation *op;
files = get_selected_files (fileman->list_files);
if (!files)
return;
op = gpa_file_sign_operation_new (GTK_WIDGET (fileman), files, FALSE);
register_operation (fileman, GPA_FILE_OPERATION (op));
}
/* Handle menu item "File/Encrypt". */
static void
file_encrypt (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
GList *files;
GpaFileEncryptOperation *op;
files = get_selected_files (fileman->list_files);
if (!files)
return;
op = gpa_file_encrypt_operation_new (GTK_WIDGET (fileman), files, FALSE);
register_operation (fileman, GPA_FILE_OPERATION (op));
}
/* Handle menu item "File/Decrypt". */
static void
file_decrypt (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
GList *files;
GpaFileDecryptOperation *op;
files = get_selected_files (fileman->list_files);
if (!files)
return;
op = gpa_file_decrypt_verify_operation_new (GTK_WIDGET (fileman), files);
register_operation (fileman, GPA_FILE_OPERATION (op));
}
/* Handle menu item "File/Close". */
static void
file_close (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
gtk_widget_destroy (GTK_WIDGET (fileman));
}
/* Handle menu item "Edit/Select All". */
static void
edit_select_all (GtkAction *action, gpointer param)
{
GpaFileManager *fileman = param;
gtk_tree_selection_select_all (gtk_tree_view_get_selection
(GTK_TREE_VIEW (fileman->list_files)));
}
/* Construct the file manager menu and toolbar widgets and return
them. */
static void
fileman_action_new (GpaFileManager *fileman, GtkWidget **menubar,
GtkWidget **toolbar)
{
static const GtkActionEntry entries[] =
{
/* Toplevel. */
{ "File", NULL, N_("_File"), NULL },
{ "Edit", NULL, N_("_Edit"), NULL },
/* File menu. */
{ "FileOpen", GTK_STOCK_OPEN, NULL, NULL,
N_("Open a file"), G_CALLBACK (file_open) },
{ "FileClear", GTK_STOCK_CLEAR, NULL, NULL,
N_("Close all files"), G_CALLBACK (file_clear) },
{ "FileSign", GPA_STOCK_SIGN, NULL, NULL,
N_("Sign the selected file"), G_CALLBACK (file_sign) },
{ "FileVerify", GPA_STOCK_VERIFY, NULL, NULL,
N_("Check signatures of selected file"), G_CALLBACK (file_verify) },
{ "FileEncrypt", GPA_STOCK_ENCRYPT, NULL, NULL,
N_("Encrypt the selected file"), G_CALLBACK (file_encrypt) },
{ "FileDecrypt", GPA_STOCK_DECRYPT, NULL, NULL,
N_("Decrypt the selected file"), G_CALLBACK (file_decrypt) },
{ "FileClose", GTK_STOCK_CLOSE, NULL, NULL,
N_("Close the window"), G_CALLBACK (file_close) },
{ "FileQuit", GTK_STOCK_QUIT, NULL, NULL,
N_("Quit the program"), G_CALLBACK (gtk_main_quit) },
/* Edit menu. */
{ "EditSelectAll", GTK_STOCK_SELECT_ALL, NULL, "<control>A",
N_("Select all files"), G_CALLBACK (edit_select_all) }
};
static const char *ui_description =
"<ui>"
" <menubar name='MainMenu'>"
" <menu action='File'>"
" <menuitem action='FileOpen'/>"
" <menuitem action='FileClear'/>"
" <separator/>"
" <menuitem action='FileSign'/>"
" <menuitem action='FileVerify'/>"
" <menuitem action='FileEncrypt'/>"
" <menuitem action='FileDecrypt'/>"
" <separator/>"
" <menuitem action='FileClose'/>"
" <menuitem action='FileQuit'/>"
" </menu>"
" <menu action='Edit'>"
" <menuitem action='EditSelectAll'/>"
" <separator/>"
" <menuitem action='EditPreferences'/>"
" <menuitem action='EditBackendPreferences'/>"
" </menu>"
" <menu action='Windows'>"
" <menuitem action='WindowsKeyringEditor'/>"
" <menuitem action='WindowsFileManager'/>"
" <menuitem action='WindowsClipboard'/>"
#ifdef ENABLE_CARD_MANAGER
" <menuitem action='WindowsCardManager'/>"
#endif
" </menu>"
" <menu action='Help'>"
#if 0
" <menuitem action='HelpContents'/>"
#endif
" <menuitem action='HelpAbout'/>"
" </menu>"
" </menubar>"
" <toolbar name='ToolBar'>"
" <toolitem action='FileOpen'/>"
" <toolitem action='FileClear'/>"
" <separator/>"
" <toolitem action='FileSign'/>"
" <toolitem action='FileVerify'/>"
" <toolitem action='FileEncrypt'/>"
" <toolitem action='FileDecrypt'/>"
" <separator/>"
" <toolitem action='EditPreferences'/>"
" <separator/>"
" <toolitem action='WindowsKeyringEditor'/>"
" <toolitem action='WindowsClipboard'/>"
#ifdef ENABLE_CARD_MANAGER
" <toolitem action='WindowsCardManager'/>"
#endif
#if 0
" <toolitem action='HelpContents'/>"
#endif
" </toolbar>"
"</ui>";
GtkAccelGroup *accel_group;
GtkActionGroup *action_group;
GtkAction *action;
GtkUIManager *ui_manager;
GError *error;
action_group = gtk_action_group_new ("MenuActions");
gtk_action_group_set_translation_domain (action_group, PACKAGE);
gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries),
fileman);
gtk_action_group_add_actions (action_group, gpa_help_menu_action_entries,
G_N_ELEMENTS (gpa_help_menu_action_entries),
fileman);
gtk_action_group_add_actions (action_group, gpa_windows_menu_action_entries,
G_N_ELEMENTS (gpa_windows_menu_action_entries),
fileman);
gtk_action_group_add_actions
(action_group, gpa_preferences_menu_action_entries,
G_N_ELEMENTS (gpa_preferences_menu_action_entries), fileman);
ui_manager = gtk_ui_manager_new ();
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
accel_group = gtk_ui_manager_get_accel_group (ui_manager);
gtk_window_add_accel_group (GTK_WINDOW (fileman), accel_group);
if (! gtk_ui_manager_add_ui_from_string (ui_manager, ui_description,
-1, &error))
{
g_message ("building fileman menus failed: %s", error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
/* Fixup the icon theme labels which are too long for the toolbar. */
action = gtk_action_group_get_action (action_group, "WindowsKeyringEditor");
g_object_set (action, "short_label", _("Keyring"), NULL);
#ifdef ENABLE_CARD_MANAGER
action = gtk_action_group_get_action (action_group, "WindowsCardManager");
g_object_set (action, "short_label", _("Card"), NULL);
#endif
/* Take care of sensitiveness of widgets. */
action = gtk_action_group_get_action (action_group, "FileSign");
add_selection_sensitive_action (fileman, action, has_selection);
action = gtk_action_group_get_action (action_group, "FileVerify");
add_selection_sensitive_action (fileman, action, has_selection);
action = gtk_action_group_get_action (action_group, "FileEncrypt");
add_selection_sensitive_action (fileman, action, has_selection);
action = gtk_action_group_get_action (action_group, "FileDecrypt");
add_selection_sensitive_action (fileman, action, has_selection);
*menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu");
*toolbar = gtk_ui_manager_get_widget (ui_manager, "/ToolBar");
gpa_toolbar_set_homogeneous (GTK_TOOLBAR (*toolbar), FALSE);
}
/* Drag and Drop handler. */
/* Handler for "drag-drop". This signal is emitted when the user
drops the selection. */
static gboolean
dnd_drop_handler (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint tim, gpointer user_data)
{
GdkAtom target_type = gdk_atom_intern ("text/uri-list", FALSE);
+ GList *targets = gdk_drag_context_list_targets(context);
+
/* If the source offers a target we request the data from her. */
- if (context->targets && g_list_find (context->targets,
+ if (targets && g_list_find (targets,
GDK_ATOM_TO_POINTER (target_type)))
{
gtk_drag_get_data (widget, context, target_type, tim);
return TRUE;
}
return FALSE;
}
/* Handler for "drag-data-received". This signal is emitted when the
data has been received from the source. */
static void
dnd_data_received_handler (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, GtkSelectionData *selection_data,
guint target_type, guint tim, gpointer user_data)
{
GpaFileManager *fileman = user_data;
gboolean dnd_success = FALSE;
gboolean delete_selection_data = FALSE;
+ // const guchar *our_selection_data = gtk_selection_data_get_data(selection_data);
+
/* Is that usable by us? */
- if (selection_data && selection_data->length >= 0 )
+ if (selection_data && gtk_selection_data_get_length(selection_data) >= 0 )
{
- if (context->action == GDK_ACTION_MOVE)
+ GdkDragAction drag_action = gdk_drag_context_get_suggested_action(context);
+
+ if (drag_action == GDK_ACTION_MOVE)
delete_selection_data = TRUE;
/* Check that we got a format we can use. */
if (target_type == DND_TARGET_URI_LIST)
{
- char *p = (char *) selection_data->data;
+ //char *p = (char *) selection_data->data;
+ char *p = (char *)gtk_selection_data_get_data(selection_data);
char **list;
int i;
list = g_uri_list_extract_uris (p);
for (i=0; list && list[i]; i++)
{
char *name = g_filename_from_uri (list[i], NULL, NULL);
if (name)
{
/* Canonical line endings are required for an uri-list. */
if ((p = strchr (name, '\r')))
*p = 0;
add_file (fileman, name);
g_free (name);
}
}
g_strfreev (list);
dnd_success = TRUE;
}
}
/* Finish the DnD processing. */
gtk_drag_finish (context, dnd_success, delete_selection_data, tim);
}
/* Construct the file list object. */
static GtkWidget *
file_list_new (GpaFileManager * fileman)
{
GtkWidget *scrollerFile;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeSelection *sel;
GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING);
GtkWidget *list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("File"), renderer,
"text",
FILE_NAME_COLUMN,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE);
g_signal_connect_swapped (sel, "changed",
G_CALLBACK (update_selection_sensitive_actions),
fileman);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (list), TRUE);
scrollerFile = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollerFile),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollerFile),
GTK_SHADOW_IN);
fileman->list_files = list;
gtk_widget_grab_focus (list);
gtk_container_add (GTK_CONTAINER (scrollerFile), list);
return scrollerFile;
}
/* Callback for the destroy signal. */
static void
file_manager_closed (GtkWidget *widget, gpointer param)
{
instance = NULL;
}
/* Construct a new class object of GpaFileManager. */
static GObject*
gpa_file_manager_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_properties)
{
GObject *object;
GpaFileManager *fileman;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *icon;
gchar *markup;
GtkWidget *menubar;
GtkWidget *file_box;
GtkWidget *file_frame;
GtkWidget *toolbar;
GtkWidget *align;
guint pt, pb, pl, pr;
/* Invoke parent's constructor. */
object = parent_class->constructor (type,
n_construct_properties,
construct_properties);
fileman = GPA_FILE_MANAGER (object);
/* Initialize. */
gpa_window_set_title (GTK_WINDOW (fileman), _("File Manager"));
gtk_window_set_default_size (GTK_WINDOW (fileman), 640, 480);
/* Realize the window so that we can create pixmaps without warnings. */
gtk_widget_realize (GTK_WIDGET (fileman));
/* Use a vbox to show the menu, toolbar and the file container. */
vbox = gtk_vbox_new (FALSE, 0);
/* Get the menu and the toolbar. */
fileman_action_new (fileman, &menubar, &toolbar);
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, TRUE, 0);
/* Add a fancy label that tells us: This is the file manager. */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
icon = gtk_image_new_from_stock ("gtk-directory", GTK_ICON_SIZE_DND);
gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, TRUE, 0);
label = gtk_label_new (NULL);
markup = g_strdup_printf ("<span font_desc=\"16\">%s</span>",
_("File Manager"));
gtk_label_set_markup (GTK_LABEL (label), markup);
g_free (markup);
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 10);
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
/* Third a hbox with the file list. */
align = gtk_alignment_new (0.5, 0.5, 1, 1);
gtk_alignment_get_padding (GTK_ALIGNMENT (align),
&pt, &pb, &pl, &pr);
gtk_alignment_set_padding (GTK_ALIGNMENT (align), pt, pb + 5,
pl + 5, pr + 5);
gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
file_box = gtk_hbox_new (TRUE, 0);
file_frame = file_list_new (fileman);
gtk_box_pack_start (GTK_BOX (file_box), file_frame, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (align), file_box);
gtk_container_add (GTK_CONTAINER (fileman), vbox);
g_signal_connect (object, "destroy",
G_CALLBACK (file_manager_closed), object);
/* Make the file box a DnD destination. */
gtk_drag_dest_set (file_box,
(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT),
dnd_target_list,
DIM (dnd_target_list),
GDK_ACTION_COPY);
g_signal_connect (file_box, "drag-drop",
G_CALLBACK (dnd_drop_handler), fileman);
g_signal_connect (file_box, "drag-data-received",
G_CALLBACK (dnd_data_received_handler), fileman);
return object;
}
static GpaFileManager *
gpa_fileman_new ()
{
GpaFileManager *fileman;
fileman = g_object_new (GPA_FILE_MANAGER_TYPE, NULL);
update_selection_sensitive_actions (fileman);
return fileman;
}
/* API */
GtkWidget *
gpa_file_manager_get_instance (void)
{
if (!instance)
{
instance = gpa_fileman_new ();
}
return GTK_WIDGET (instance);
}
gboolean gpa_file_manager_is_open (void)
{
return (instance != NULL);
}
void gpa_file_manager_open_file (GpaFileManager *fileman,
const gchar *filename)
{
if (!add_file (fileman, filename))
gpa_window_error (_("The file is already open."),
GTK_WIDGET (fileman));
/* FIXME: Release filename? */
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Feb 23, 7:17 PM (5 h, 6 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
f8/85/c30b70124207ed4eac013bd03277
Attached To
rGPA Gnu Privacy Assistant
Event Timeline
Log In to Comment