summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Patrick Griffis <tingping@tingping.se>2016-02-17 10:09:31 -0500
committerGravatar Patrick Griffis <tingping@tingping.se>2016-02-17 15:15:41 -0500
commitb6bb8fb323f3885e106c0606de050c0437ccf81f (patch)
tree4b45ef1277ce646a8b42eea7ae52b4264d89b2cf /src
parent2ad81ecf9806b3842fed99afe29adcb327801b83 (diff)
Redesign destination combobox
Diffstat (limited to 'src')
-rw-r--r--src/trg-destination-combo.c286
-rw-r--r--src/trg-destination-combo.h24
-rw-r--r--src/trg-torrent-move-dialog.c5
3 files changed, 113 insertions, 202 deletions
diff --git a/src/trg-destination-combo.c b/src/trg-destination-combo.c
index 0bbd983..a361bae 100644
--- a/src/trg-destination-combo.c
+++ b/src/trg-destination-combo.c
@@ -30,25 +30,24 @@
#include "trg-destination-combo.h"
#include "util.h"
-G_DEFINE_TYPE(TrgDestinationCombo, trg_destination_combo,
- GTK_TYPE_COMBO_BOX)
-#define TRG_DESTINATION_COMBO_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_DESTINATION_COMBO, TrgDestinationComboPrivate))
-typedef struct _TrgDestinationComboPrivate TrgDestinationComboPrivate;
+struct _TrgDestinationCombo {
+ GtkComboBox parent_instance;
+};
-struct _TrgDestinationComboPrivate {
+typedef struct {
TrgClient *client;
gchar *last_selection;
- GtkWidget *entry;
- GtkCellRenderer *text_renderer;
-};
+} TrgDestinationComboPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE(TrgDestinationCombo, trg_destination_combo,
+ GTK_TYPE_COMBO_BOX)
enum {
PROP_0, PROP_CLIENT, PROP_LAST_SELECTION
};
enum {
- DEST_DEFAULT, DEST_LABEL, DEST_EXISTING, DEST_USERADD
+ DEST_DEFAULT, DEST_LABEL, DEST_EXISTING
};
enum {
@@ -58,7 +57,7 @@ enum {
static void trg_destination_combo_finalize(GObject * object)
{
TrgDestinationComboPrivate *priv =
- TRG_DESTINATION_COMBO_GET_PRIVATE(object);
+ trg_destination_combo_get_instance_private(TRG_DESTINATION_COMBO(object));
g_free(priv->last_selection);
}
@@ -68,7 +67,7 @@ trg_destination_combo_get_property(GObject * object,
GValue * value, GParamSpec * pspec)
{
TrgDestinationComboPrivate *priv =
- TRG_DESTINATION_COMBO_GET_PRIVATE(object);
+ trg_destination_combo_get_instance_private(TRG_DESTINATION_COMBO(object));
switch (property_id) {
case PROP_CLIENT:
g_value_set_pointer(value, priv->client);
@@ -89,7 +88,7 @@ trg_destination_combo_set_property(GObject * object,
GParamSpec * pspec)
{
TrgDestinationComboPrivate *priv =
- TRG_DESTINATION_COMBO_GET_PRIVATE(object);
+ trg_destination_combo_get_instance_private(TRG_DESTINATION_COMBO(object));
switch (property_id) {
case PROP_CLIENT:
priv->client = g_value_get_pointer(value);
@@ -119,7 +118,7 @@ static gboolean g_slist_str_set_add(GSList ** list, const gchar * string)
void trg_destination_combo_save_selection(TrgDestinationCombo * combo_box)
{
TrgDestinationComboPrivate *priv =
- TRG_DESTINATION_COMBO_GET_PRIVATE(combo_box);
+ trg_destination_combo_get_instance_private(combo_box);
GtkTreeIter iter;
if (priv->last_selection
@@ -130,47 +129,16 @@ void trg_destination_combo_save_selection(TrgDestinationCombo * combo_box)
TrgPrefs *prefs = trg_client_get_prefs(priv->client);
gchar *text;
- gtk_tree_model_get(model, &iter, DEST_COLUMN_LABEL, &text, -1);
+ gtk_tree_model_get(model, &iter, DEST_COLUMN_DIR, &text, -1);
trg_prefs_set_string(prefs, priv->last_selection, text,
TRG_PREFS_CONNECTION);
g_free(text);
}
}
-static void
-gtk_combo_box_entry_active_changed(GtkComboBox * combo_box,
- gpointer user_data)
+static inline GtkEntry *trg_destination_combo_get_entry(TrgDestinationCombo * combo)
{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gboolean editableEntry = TRUE;
-
- if (gtk_combo_box_get_active_iter(combo_box, &iter)) {
- GtkEntry *entry =
- trg_destination_combo_get_entry(TRG_DESTINATION_COMBO
- (combo_box));
-
- if (entry) {
- GValue value = G_VALUE_INIT;
- guint type;
-
- model = gtk_combo_box_get_model(combo_box);
-
- gtk_tree_model_get_value(model, &iter, DEST_COLUMN_LABEL,
- &value);
- gtk_tree_model_get(model, &iter, DEST_COLUMN_TYPE, &type, -1);
-
- g_object_set_property(G_OBJECT(entry), "text", &value);
- g_value_unset(&value);
-
- if (type == DEST_LABEL)
- editableEntry = FALSE;
- }
- }
- gtk_editable_set_editable(GTK_EDITABLE
- (trg_destination_combo_get_entry
- (TRG_DESTINATION_COMBO(combo_box))),
- editableEntry);
+ return GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo)));
}
gboolean trg_destination_combo_has_text(TrgDestinationCombo * combo)
@@ -181,29 +149,6 @@ gboolean trg_destination_combo_has_text(TrgDestinationCombo * combo)
return strlen(text) > 0;
}
-GtkEntry *trg_destination_combo_get_entry(TrgDestinationCombo * combo)
-{
- TrgDestinationComboPrivate *priv =
- TRG_DESTINATION_COMBO_GET_PRIVATE(combo);
- return GTK_ENTRY(priv->entry);
-}
-
-static void
-add_entry_cb(GtkEntry * entry,
- GtkEntryIconPosition icon_pos,
- GdkEvent * event, gpointer user_data)
-{
- GtkComboBox *combo = GTK_COMBO_BOX(user_data);
- GtkTreeModel *model = gtk_combo_box_get_model(combo);
- GtkTreeIter iter;
-
- gtk_list_store_insert_with_values(GTK_LIST_STORE(model), &iter,
- INT_MAX, DEST_COLUMN_LABEL, "",
- DEST_COLUMN_DIR, "",
- DEST_COLUMN_TYPE, DEST_USERADD, -1);
- gtk_combo_box_set_active_iter(combo, &iter);
-}
-
struct findDupeArg {
const gchar *dir;
gboolean isDupe;
@@ -226,12 +171,11 @@ trg_destination_combo_insert_check_dupe_foreach(GtkTreeModel * model,
static void
trg_destination_combo_insert(GtkComboBox * box,
const gchar * label,
- const gchar * dir, guint type,
- const gchar * lastDestination)
+ const gchar * dir,
+ guint type)
{
GtkTreeModel *model = gtk_combo_box_get_model(box);
gchar *comboLabel;
- GtkTreeIter iter;
if (type == DEST_EXISTING) {
struct findDupeArg args;
@@ -248,110 +192,88 @@ trg_destination_combo_insert(GtkComboBox * box,
comboLabel =
label ? g_strdup_printf("%s (%s)", label, dir) : g_strdup(dir);
- gtk_list_store_insert_with_values(GTK_LIST_STORE(model), &iter,
- INT_MAX, DEST_COLUMN_LABEL,
- comboLabel, DEST_COLUMN_DIR, dir,
+ gtk_list_store_insert_with_values(GTK_LIST_STORE(model), NULL, -1,
+ DEST_COLUMN_LABEL, comboLabel,
+ DEST_COLUMN_DIR, dir,
DEST_COLUMN_TYPE, type, -1);
-
- if (lastDestination && !g_strcmp0(lastDestination, comboLabel))
- gtk_combo_box_set_active_iter(box, &iter);
-
g_free(comboLabel);
}
-static GObject *trg_destination_combo_constructor(GType type,
- guint
- n_construct_properties,
- GObjectConstructParam *
- construct_params)
+gchar *trg_destination_combo_get_dir(TrgDestinationCombo * combo)
{
- GObject *object = G_OBJECT_CLASS
- (trg_destination_combo_parent_class)->constructor(type,
- n_construct_properties,
- construct_params);
- TrgDestinationComboPrivate *priv =
- TRG_DESTINATION_COMBO_GET_PRIVATE(object);
+ GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
+ GtkTreeIter iter;
+ if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) {
+ gchar *value;
+ guint type;
+
+ gtk_tree_model_get(model, &iter, DEST_COLUMN_TYPE, &type, -1);
+
+ if (type == DEST_LABEL) {
+ gtk_tree_model_get(model, &iter, DEST_COLUMN_DIR, &value, -1);
+ return value;
+ }
+ }
+
+ return
+ g_strdup(gtk_entry_get_text
+ (trg_destination_combo_get_entry(combo)));
+}
+
+static void
+load_directory_model(TrgDestinationCombo *self)
+{
+ TrgDestinationComboPrivate *priv = trg_destination_combo_get_instance_private(self);
TrgClient *client = priv->client;
TrgPrefs *prefs = trg_client_get_prefs(client);
GSList *dirs = NULL, *sli;
GList *li, *list;
- GtkTreeRowReference *rr;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkListStore *comboModel;
+
JsonArray *savedDestinations;
gchar *defaultDir;
- gchar *lastDestination = NULL;
-
- comboModel = gtk_list_store_new(N_DEST_COLUMNS, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_UINT);
- gtk_combo_box_set_model(GTK_COMBO_BOX(object),
- GTK_TREE_MODEL(comboModel));
- g_object_unref(comboModel);
-
- g_signal_connect(object, "changed",
- G_CALLBACK(gtk_combo_box_entry_active_changed), NULL);
-
- priv->entry = gtk_entry_new();
- gtk_container_add(GTK_CONTAINER(object), priv->entry);
-
- priv->text_renderer = gtk_cell_renderer_text_new();
- gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(object),
- priv->text_renderer, TRUE);
-
- gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(object),
- priv->text_renderer, "text", 0, NULL);
-
- g_slist_foreach(dirs, (GFunc) g_free, NULL);
- g_slist_free(dirs);
-
- gtk_entry_set_icon_from_stock(GTK_ENTRY(priv->entry),
- GTK_ENTRY_ICON_SECONDARY,
- GTK_STOCK_CLEAR);
-
- g_signal_connect(priv->entry, "icon-release",
- G_CALLBACK(add_entry_cb), object);
+ /* Add default dir */
defaultDir =
g_strdup(session_get_download_dir(trg_client_get_session(client)));
rm_trailing_slashes(defaultDir);
+ trg_destination_combo_insert(GTK_COMBO_BOX(self),
+ NULL,
+ defaultDir, DEST_DEFAULT);
+ g_free (defaultDir);
+
+
+ /* Add saved dirs */
savedDestinations =
trg_prefs_get_array(prefs, TRG_PREFS_KEY_DESTINATIONS,
TRG_PREFS_CONNECTION);
-
- if (priv->last_selection)
- lastDestination = trg_prefs_get_string(prefs, priv->last_selection,
- TRG_PREFS_CONNECTION);
-
- trg_destination_combo_insert(GTK_COMBO_BOX(object),
- NULL,
- defaultDir, DEST_DEFAULT,
- lastDestination);
- gtk_combo_box_set_active(GTK_COMBO_BOX(object), 0);
-
if (savedDestinations) {
list = json_array_get_elements(savedDestinations);
if (list) {
for (li = list; li; li = g_list_next(li)) {
JsonObject *obj =
json_node_get_object((JsonNode *) li->data);
- trg_destination_combo_insert(GTK_COMBO_BOX(object),
+ trg_destination_combo_insert(GTK_COMBO_BOX(self),
json_object_get_string_member
- (obj, TRG_PREFS_SUBKEY_LABEL),
- json_object_get_string_member
- (obj,
- TRG_PREFS_KEY_DESTINATIONS_SUBKEY_DIR),
- DEST_LABEL, lastDestination);
+ (obj, TRG_PREFS_SUBKEY_LABEL),
+ json_object_get_string_member
+ (obj, TRG_PREFS_KEY_DESTINATIONS_SUBKEY_DIR),
+ DEST_LABEL);
}
g_list_free(list);
}
}
+
+ /* Add all previously used download dirs */
list = g_hash_table_get_values(trg_client_get_torrent_table(client));
for (li = list; li; li = g_list_next(li)) {
+ GtkTreeRowReference *rr;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+
rr = (GtkTreeRowReference *) li->data;
model = gtk_tree_row_reference_get_model(rr);
path = gtk_tree_row_reference_get_path(rr);
@@ -376,38 +298,48 @@ static GObject *trg_destination_combo_constructor(GType type,
}
for (sli = dirs; sli; sli = g_slist_next(sli))
- trg_destination_combo_insert(GTK_COMBO_BOX(object),
+ trg_destination_combo_insert(GTK_COMBO_BOX(self),
NULL,
(gchar *) sli->data,
- DEST_EXISTING, lastDestination);
+ DEST_EXISTING);
+ g_slist_free_full (dirs, g_free);
g_list_free(list);
- g_free(defaultDir);
- g_free(lastDestination);
+}
- return object;
+static void set_text_column(GtkCellLayout *layout, guint col)
+{
+ GList *cells = gtk_cell_layout_get_cells (layout);
+ g_assert (cells != NULL);
+ gtk_cell_layout_set_attributes (layout, GTK_CELL_RENDERER(cells->data), "text", col, NULL);
+ g_list_free (cells);
}
-gchar *trg_destination_combo_get_dir(TrgDestinationCombo * combo)
+static void trg_destination_combo_constructed(GObject *object)
{
- GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
- GtkTreeIter iter;
+ TrgDestinationCombo *self = TRG_DESTINATION_COMBO (object);
+ TrgDestinationComboPrivate *priv =
+ trg_destination_combo_get_instance_private(self);
+ TrgPrefs *prefs = trg_client_get_prefs(priv->client);
- if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) {
- gchar *value;
- guint type;
+ G_OBJECT_CLASS(trg_destination_combo_parent_class)->constructed(object);
- gtk_tree_model_get(model, &iter, DEST_COLUMN_TYPE, &type, -1);
+ load_directory_model (self);
+ set_text_column (GTK_CELL_LAYOUT(self), DEST_COLUMN_LABEL);
- if (type == DEST_LABEL) {
- gtk_tree_model_get(model, &iter, DEST_COLUMN_DIR, &value, -1);
- return g_strdup(value);
- }
+ /* Must be set after constructed */
+ if (priv->last_selection) {
+ /* Restore any previous selection */
+ char *lastDestination = trg_prefs_get_string(prefs, priv->last_selection,
+ TRG_PREFS_CONNECTION);
+ if (!gtk_combo_box_set_active_id (GTK_COMBO_BOX(object), lastDestination))
+ g_warning ("Last selection was not a valid ID");
+ g_free(lastDestination);
+ }
+ else {
+ /* DefaultDir is the first item otherwise */
+ gtk_combo_box_set_active (GTK_COMBO_BOX(object), 0);
}
-
- return
- g_strdup(gtk_entry_get_text
- (trg_destination_combo_get_entry(combo)));
}
static void
@@ -415,27 +347,19 @@ trg_destination_combo_class_init(TrgDestinationComboClass * klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
- g_type_class_add_private(klass, sizeof(TrgDestinationComboPrivate));
-
object_class->get_property = trg_destination_combo_get_property;
object_class->set_property = trg_destination_combo_set_property;
object_class->finalize = trg_destination_combo_finalize;
- object_class->constructor = trg_destination_combo_constructor;
+ object_class->constructed = trg_destination_combo_constructed;
g_object_class_install_property(object_class,
PROP_CLIENT,
g_param_spec_pointer("trg-client",
"TClient",
"Client",
- G_PARAM_READWRITE
- |
- G_PARAM_CONSTRUCT_ONLY
- |
- G_PARAM_STATIC_NAME
- |
- G_PARAM_STATIC_NICK
- |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class,
PROP_LAST_SELECTION,
@@ -445,19 +369,25 @@ trg_destination_combo_class_init(TrgDestinationComboClass * klass)
"LastSelectionKey", NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_STATIC_STRINGS));
}
static void trg_destination_combo_init(TrgDestinationCombo * self)
{
+ GtkListStore *store;
+
+ store = gtk_list_store_new(N_DEST_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
+ gtk_combo_box_set_model(GTK_COMBO_BOX(self), GTK_TREE_MODEL(store));
+ gtk_combo_box_set_id_column (GTK_COMBO_BOX(self), DEST_COLUMN_DIR);
+ gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(self), DEST_COLUMN_LABEL);
+ g_object_unref(store);
}
GtkWidget *trg_destination_combo_new(TrgClient * client,
const gchar * lastSelectionKey)
{
return GTK_WIDGET(g_object_new(TRG_TYPE_DESTINATION_COMBO,
+ "has-entry", TRUE,
"trg-client", client,
"last-selection-key", lastSelectionKey,
NULL));
diff --git a/src/trg-destination-combo.h b/src/trg-destination-combo.h
index 9ab5076..9ece8cc 100644
--- a/src/trg-destination-combo.h
+++ b/src/trg-destination-combo.h
@@ -26,32 +26,14 @@
#include "trg-client.h"
G_BEGIN_DECLS
-#define TRG_TYPE_DESTINATION_COMBO trg_destination_combo_get_type()
-#define TRG_DESTINATION_COMBO(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRG_TYPE_DESTINATION_COMBO, TrgDestinationCombo))
-#define TRG_DESTINATION_COMBO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), TRG_TYPE_DESTINATION_COMBO, TrgDestinationComboClass))
-#define TRG_IS_DESTINATION_COMBO(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRG_TYPE_DESTINATION_COMBO))
-#define TRG_IS_DESTINATION_COMBO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), TRG_TYPE_DESTINATION_COMBO))
-#define TRG_DESTINATION_COMBO_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), TRG_TYPE_DESTINATION_COMBO, TrgDestinationComboClass))
- typedef struct {
- GtkComboBox parent;
-} TrgDestinationCombo;
-
-typedef struct {
- GtkComboBoxClass parent_class;
-} TrgDestinationComboClass;
-
-GType trg_destination_combo_get_type(void);
+
+#define TRG_TYPE_DESTINATION_COMBO (trg_destination_combo_get_type())
+G_DECLARE_FINAL_TYPE(TrgDestinationCombo, trg_destination_combo, TRG, DESTINATION_COMBO, GtkComboBox)
GtkWidget *trg_destination_combo_new(TrgClient * client,
const gchar * lastSelectionKey);
gchar *trg_destination_combo_get_dir(TrgDestinationCombo * combo);
gboolean trg_destination_combo_has_text(TrgDestinationCombo * combo);
-GtkEntry *trg_destination_combo_get_entry(TrgDestinationCombo * combo);
void trg_destination_combo_save_selection(TrgDestinationCombo * combo_box);
G_END_DECLS
diff --git a/src/trg-torrent-move-dialog.c b/src/trg-torrent-move-dialog.c
index 555ea09..fec1932 100644
--- a/src/trg-torrent-move-dialog.c
+++ b/src/trg-torrent-move-dialog.c
@@ -80,7 +80,7 @@ trg_torrent_move_response_cb(GtkDialog * dlg, gint res_id, gpointer data)
gtk_widget_destroy(GTK_WIDGET(dlg));
}
-static void location_changed(GtkWidget * w, gpointer data)
+static void location_changed(GtkComboBox * w, gpointer data)
{
TrgTorrentMoveDialogPrivate *priv =
TRG_TORRENT_MOVE_DIALOG_GET_PRIVATE(data);
@@ -114,8 +114,7 @@ static GObject *trg_torrent_move_dialog_constructor(GType type,
w = priv->location_combo =
trg_destination_combo_new(priv->client,
TRG_PREFS_KEY_LAST_MOVE_DESTINATION);
- g_signal_connect(trg_destination_combo_get_entry
- (TRG_DESTINATION_COMBO(w)), "changed",
+ g_signal_connect(w, "changed",
G_CALLBACK(location_changed), object);
hig_workarea_add_row(t, &row, _("Location:"), w, NULL);