Browse Source

Make the interface reactive.

Disable the OK/Confirm button until a workable action (sign and/or
encrypt) has been defined by the user. Also only enable the
detached signature button when it makes sense, i.e. when signing
is enabled and encryption is disabled.

Refactor the code to get rid of the yki_ctx_t structure, which is
replaced by a yki_encrypt_data_t structure that is internal to
the encrypt module.
master
Damien Goutte-Gattat 2 years ago
parent
commit
2a7ca83544
  1. 3
      src/Makefile.am
  2. 68
      src/encrypt.c
  3. 5
      src/encrypt.h
  4. 10
      src/yki.c
  5. 47
      src/ykiutil.c
  6. 51
      src/ykiutil.h

3
src/Makefile.am

@ -1,8 +1,7 @@
bin_PROGRAMS = yki
yki_SOURCES = yki.c gpgutil.c gpgutil.h error.c error.h errors.h \
ykiutil.c ykiutil.h encrypt.c encrypt.h \
yki-encrypt.ui resources.xml
encrypt.c encrypt.h yki-encrypt.ui resources.xml
nodist_yki_SOURCES = resources.c

68
src/encrypt.c

@ -34,22 +34,51 @@
/* GUI stuff. */
typedef struct {
gpgme_ctx_t gpgme;
GtkListStore *public_keys;
unsigned selected_keys;
gboolean symmetric;
gboolean sign;
gboolean detached;
GtkWidget *ok_button;
GtkWidget *detached_button;
} yki_encrypt_data_t;
static void
update_buttons(yki_encrypt_data_t *yki)
{
gtk_widget_set_sensitive(yki->ok_button,
yki->symmetric ||
yki->selected_keys ||
yki->sign);
gtk_widget_set_sensitive(yki->detached_button,
yki->sign &&
! ( yki->symmetric || yki->selected_keys));
}
static void
symmetric_encrypt_toggled(GtkWidget *widget, gpointer data)
{
((yki_ctx_t *)data)->symmetric = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
((yki_encrypt_data_t *)data)->symmetric = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
update_buttons((yki_encrypt_data_t *)data);
}
static void
sign_toggled(GtkWidget *widget, gpointer data)
{
((yki_ctx_t *)data)->sign = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
((yki_encrypt_data_t *)data)->sign = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
update_buttons((yki_encrypt_data_t *)data);
}
static void
detach_sign_toggled(GtkWidget *widget, gpointer data)
{
((yki_ctx_t *)data)->detached = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
((yki_encrypt_data_t *)data)->detached = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
}
static void
@ -57,7 +86,7 @@ public_key_toggled(GtkCellRendererToggle *renderer,
gchar *path,
gpointer data)
{
yki_ctx_t *yki = (yki_ctx_t *)data;
yki_encrypt_data_t *yki = (yki_encrypt_data_t *)data;
GtkTreeIter iter;
gboolean selected;
@ -68,10 +97,12 @@ public_key_toggled(GtkCellRendererToggle *renderer,
yki->selected_keys += selected ? 1 : -1;
gtk_list_store_set(GTK_LIST_STORE(yki->public_keys), &iter, 0, selected, -1);
update_buttons(yki);
}
static GtkDialog *
create_encrypt_dialog(yki_ctx_t *yki)
create_encrypt_dialog(yki_encrypt_data_t *yki)
{
GtkBuilder *builder;
GObject *widget;
@ -99,6 +130,11 @@ create_encrypt_dialog(yki_ctx_t *yki)
column = gtk_tree_view_column_new_with_attributes("User ID", renderer, "text", 1, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
yki->ok_button = GTK_WIDGET(gtk_builder_get_object(builder, "btnOK"));
yki->detached_button = GTK_WIDGET(gtk_builder_get_object(builder, "chkDetachSign"));
update_buttons(yki);
return GTK_DIALOG(gtk_builder_get_object(builder, "dlgEncrypt"));
}
@ -150,7 +186,7 @@ free_key_in_list(GtkTreeModel *store, GtkTreePath *path, GtkTreeIter *iter, gpoi
}
static gpgme_key_t *
get_selected_keys(yki_ctx_t *yki)
get_selected_keys(yki_encrypt_data_t *yki)
{
gpgme_key_t *keys;
GtkTreeIter iter;
@ -183,7 +219,7 @@ get_selected_keys(yki_ctx_t *yki)
#define yki_can_encrypt(yki) ((yki).selected_keys || (yki).symmetric || (yki).sign)
static int
do_encrypt(yki_ctx_t *yki, gpgme_data_t in, gpgme_data_t out, GError **error)
do_encrypt(yki_encrypt_data_t *yki, gpgme_data_t in, gpgme_data_t out, GError **error)
{
gpgme_error_t gerr = 0;
@ -218,21 +254,25 @@ do_encrypt(yki_ctx_t *yki, gpgme_data_t in, gpgme_data_t out, GError **error)
int
yki_encrypt(yki_ctx_t *yki, const char *file, GError **error)
yki_encrypt(gpgme_ctx_t gpgme, const char *file, GError **error)
{
yki_encrypt_data_t yki;
GtkDialog *dlg;
gpgutil_file_t in, out;
gchar *outname;
int ret;
g_assert(yki && file);
g_assert(gpgme && file);
yki.gpgme = gpgme;
yki.selected_keys = 0;
yki.symmetric = yki.sign = yki.detached = FALSE;
in.buffer = out.buffer = NULL;
dlg = create_encrypt_dialog(yki);
ret = populate_public_key_list(yki->gpgme, yki->public_keys, error);
dlg = create_encrypt_dialog(&yki);
ret = populate_public_key_list(gpgme, yki.public_keys, error);
if ( ret && gtk_dialog_run(dlg) == GTK_RESPONSE_OK && yki_can_encrypt(*yki) ) {
if ( ret && gtk_dialog_run(dlg) == GTK_RESPONSE_OK && yki_can_encrypt(yki) ) {
ret = gpgutil_open_file(file, "r", &in, error);
if ( ret ) {
@ -242,13 +282,13 @@ yki_encrypt(yki_ctx_t *yki, const char *file, GError **error)
}
if ( ret )
ret = do_encrypt(yki, in.buffer, out.buffer, error);
ret = do_encrypt(&yki, in.buffer, out.buffer, error);
}
gpgutil_close_file(&in, NULL);
gpgutil_close_file(&out, NULL);
gtk_tree_model_foreach(GTK_TREE_MODEL(yki->public_keys), free_key_in_list, NULL);
gtk_tree_model_foreach(GTK_TREE_MODEL(yki.public_keys), free_key_in_list, NULL);
gtk_widget_destroy(GTK_WIDGET(dlg));
return ret;

5
src/encrypt.h

@ -19,14 +19,15 @@
#ifndef ICP20200503_ENCRYPT_H
#define ICP20200503_ENCRYPT_H
#include "ykiutil.h"
#include <glib.h>
#include <gpgme.h>
#ifdef __cpluscplus
extern "C" {
#endif
int
yki_encrypt(yki_ctx_t *, const char *, GError **);
yki_encrypt(gpgme_ctx_t, const char *, GError **);
#ifdef __cplusplus
}

10
src/yki.c

@ -29,7 +29,7 @@
#include "error.h"
#include "encrypt.h"
#include "ykiutil.h"
#include "gpgutil.h"
static gboolean
@ -53,7 +53,7 @@ check_non_option_args(GOptionContext *parser, GOptionGroup *group, gpointer data
int
main(int argc, char **argv)
{
yki_ctx_t yki;
gpgme_ctx_t gpgme;
GError *error = NULL;
gboolean encrypt;
gchar **files;
@ -80,11 +80,11 @@ main(int argc, char **argv)
g_option_context_parse(parser, &argc, &argv, &error);
if ( ! error )
yki_init(&yki, &error);
gpgme = gpgutil_initialize(&error);
if ( ! error ) {
if ( encrypt )
yki_encrypt(&yki, files[0], &error);
yki_encrypt(gpgme, files[0], &error);
else
g_set_error(&error, YKI_ERROR, YKI_ERROR_NOT_IMPLEMENTED, "Cannot decrypt");
}
@ -94,7 +94,7 @@ main(int argc, char **argv)
g_option_context_free(parser);
g_strfreev(files);
yki_release(&yki);
gpgme_release(gpgme);
return error ? EXIT_FAILURE : EXIT_SUCCESS;
}

47
src/ykiutil.c

@ -1,47 +0,0 @@
/*
* Yorkie - A task-oriented GnuPG frontend
* Copyright (C) 2020 Damien Goutte-Gattat
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "ykiutil.h"
#include "gpgutil.h"
int
yki_init(yki_ctx_t *yki, GError **error)
{
g_assert(yki);
yki->gpgme = gpgutil_initialize(error);
yki->public_keys = NULL;
yki->selected_keys = 0;
yki->symmetric = yki->sign = yki->detached = FALSE;
return yki->gpgme != NULL;
}
void
yki_release(yki_ctx_t *yki)
{
g_assert(yki);
if ( yki->gpgme )
gpgme_release(yki->gpgme);
}

51
src/ykiutil.h

@ -1,51 +0,0 @@
/*
* Yorkie - A task-oriented GnuPG frontend
* Copyright (C) 2020 Damien Goutte-Gattat
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20200503_YKIUTIL_H
#define ICP20200503_YKIUTIL_H
#include <glib.h>
#include <gtk/gtk.h>
#include <gpgme.h>
typedef struct {
gpgme_ctx_t gpgme;
GtkListStore *public_keys;
unsigned selected_keys;
gboolean symmetric;
gboolean sign;
gboolean detached;
} yki_ctx_t;
#ifdef __cpluscplus
extern "C" {
#endif
int
yki_init(yki_ctx_t *, GError **);
void
yki_release(yki_ctx_t *);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20200503_YKIUTIL_H */
Loading…
Cancel
Save