Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34602029
fileman.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
37 KB
Subscribers
None
fileman.c
View Options
/* 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
GActionEntry
entries
[]
=
{
{
"File"
,
NULL
},
{
"Edit"
,
NULL
},
{
"file_open"
,
file_open
},
{
"file_clear"
,
file_clear
},
{
"file_sign"
,
file_sign
},
{
"file_verify"
,
file_verify
},
{
"file_encrypt"
,
file_encrypt
},
{
"file_decrypt"
,
file_decrypt
},
{
"file_close"
,
file_close
},
{
"file_quit"
,
g_application_quit
},
{
"edit_select_all"
,
edit_select_all
},
};
static
const
GtkActionEntry
old_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
(
g_application_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>";
*/
static
const
char
*
menu_string
=
{
"<interface>"
"<menu id='main_menu'>"
"<submenu>"
"<attribute name='label' translatable='yes'>_File</attribute>"
"<section>"
"<item>"
"<attribute name='label' translatable='yes'>Open</attribute>"
"<attribute name='action'>app.file_close</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Clear</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"</section>"
"<section>"
"<item>"
"<attribute name='label' translatable='yes'>Sign</attribute>"
"<attribute name='action'>app.file_close</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Verify</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Encrypt</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Decrypt</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"</section>"
"<section>"
"<item>"
"<attribute name='label' translatable='yes'>Close</attribute>"
"<attribute name='action'>app.file_close</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Quit</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"</section>"
"</submenu>"
"<submenu>"
"<attribute name='label' translatable='yes'>Edit</attribute>"
"<section>"
"<item>"
"<attribute name='label' translatable='yes'>Mark All</attribute>"
"<attribute name='action'>app.file_close</attribute>"
"</item>"
"</section>"
"<section>"
"<item>"
"<attribute name='label' translatable='yes'>Backend Settings</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Settings</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"</section>"
"</submenu>"
"<submenu>"
"<attribute name='label' translatable='yes'>Window</attribute>"
"<item>"
"<attribute name='label' translatable='yes'>Keyring Manager</attribute>"
"<attribute name='action'>app.file_close</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>File Manager</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Clipboard</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"<item>"
"<attribute name='label' translatable='yes'>Card Manager</attribute>"
"<attribute name='action'>app.file_quit</attribute>"
"</item>"
"</submenu>"
"<submenu>"
"<attribute name='label' translatable='yes'>Help</attribute>"
"<item>"
"<attribute name='label' translatable='yes'>About</attribute>"
"<attribute name='action'>app.help_about</attribute>"
"</item>"
"</submenu>"
"</menu>"
"<object id='toolbar' class='GtkToolbar'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='show_arrow'>False</property>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>document-open</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>edit-clear</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkSeparatorToolItem'>"
"</object>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>sign</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>verify</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>encrypt</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>decrypt</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkSeparatorToolItem'>"
"</object>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>preferences-desktop</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkSeparatorToolItem'>"
"</object>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>keyring</property>"
"<property name='action-name'>app.windows_keyring_editor</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>edit-paste</property>"
"<property name='action-name'>app.windows_clipboard</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"<child>"
"<object class='GtkToolButton'>"
"<property name='visible'>True</property>"
"<property name='can_focus'>False</property>"
"<property name='use_underline'>True</property>"
"<property name='icon_name'>smartcard</property>"
"<property name='action-name'>app.windows_card_manager</property>"
"</object>"
"<packing>"
"<property name='expand'>False</property>"
"<property name='homogeneous'>True</property>"
"</packing>"
"</child>"
"</object>"
"</interface>"
};
/*
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);
*/
GError
**
err
;
GtkBuilder
*
gtk_builder
=
gtk_builder_new_from_string
(
menu_string
,
-1
);
if
(
gtk_builder_add_from_string
(
gtk_builder
,
menu_string
,
-1
,
err
)
==
0
)
{
printf
(
"ERROR: %s
\n
"
,
(
*
err
)
->
message
);
}
GMenuModel
*
menu_bar_model
=
G_MENU_MODEL
(
gtk_builder_get_object
(
GTK_BUILDER
(
gtk_builder
),
"main_menu"
));
*
menubar
=
gtk_menu_bar_new_from_model
(
menu_bar_model
);
/*
GMenuModel *popup_menu_model = G_MENU_MODEL (gtk_builder_get_object (GTK_BUILDER (gtk_builder), "popupmenu"));
*popup = gtk_menu_new_from_model (popup_menu_model);
*/
GObject
*
grid
=
gtk_builder_get_object
(
GTK_BUILDER
(
gtk_builder
),
"toolbar"
);
GtkCssProvider
*
css_provider
=
gtk_css_provider_new
();
GdkDisplay
*
display
=
gdk_display_get_default
();
GdkScreen
*
screen
=
gdk_display_get_default_screen
(
display
);
gtk_style_context_add_provider_for_screen
(
screen
,
GTK_STYLE_PROVIDER
(
css_provider
),
GTK_STYLE_PROVIDER_PRIORITY_USER
);
gtk_css_provider_load_from_data
(
css_provider
,
"#toolbar {
\n
"
//" padding-left: 55px;\n"
// " padding-right: 5px;\n"
// " border-radius: 3px;\n"
"}
\n
"
,
-1
,
NULL
);
GtkStyleContext
*
style_context
;
style_context
=
gtk_widget_get_style_context
(
GTK_WIDGET
(
grid
));
//gtk_widget_add_css_class (grid, "toolbar");
*
toolbar
=
grid
;
// We must set the name to the toolbar for css to recognize it
gtk_widget_set_name
(
*
toolbar
,
"toolbar"
);
gtk_style_context_add_class
(
style_context
,
"toolbar"
);
GtkApplication
*
gpa_app
=
get_gpa_application
();
g_action_map_add_action_entries
(
G_ACTION_MAP
(
gpa_app
),
gpa_windows_menu_g_action_entries
,
G_N_ELEMENTS
(
gpa_windows_menu_g_action_entries
),
fileman
);
g_action_map_add_action_entries
(
G_ACTION_MAP
(
gpa_app
),
entries
,
G_N_ELEMENTS
(
entries
),
fileman
);
g_action_map_add_action_entries
(
G_ACTION_MAP
(
gpa_app
),
gpa_help_menu_g_action_entries
,
G_N_ELEMENTS
(
gpa_help_menu_g_action_entries
),
fileman
);
g_action_map_add_action_entries
(
G_ACTION_MAP
(
gpa_app
),
gpa_preferences_menu_g_action_entries
,
G_N_ELEMENTS
(
gpa_preferences_menu_g_action_entries
),
fileman
);
}
/* 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
(
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
&&
gtk_selection_data_get_length
(
selection_data
)
>=
0
)
{
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
*
)
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_box_new
(
GTK_ORIENTATION_VERTICAL
,
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_box_new
(
GTK_ORIENTATION_HORIZONTAL
,
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_box_new
(
GTK_ORIENTATION_HORIZONTAL
,
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-c
Expires
Sun, Jan 18, 4:32 PM (4 h, 42 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
f5/eb/00ac4f8a5ed952188de6a1f7f7a4
Attached To
rGPA Gnu Privacy Assistant
Event Timeline
Log In to Comment