aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/gui/contact-list-editor/contact-list-editor.ui70
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.c232
2 files changed, 293 insertions, 9 deletions
diff --git a/addressbook/gui/contact-list-editor/contact-list-editor.ui b/addressbook/gui/contact-list-editor/contact-list-editor.ui
index 31bc2fc1a6..6cef3e2551 100644
--- a/addressbook/gui/contact-list-editor/contact-list-editor.ui
+++ b/addressbook/gui/contact-list-editor/contact-list-editor.ui
@@ -258,6 +258,76 @@
</packing>
</child>
<child>
+ <object class="GtkButton" id="top-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-goto-top</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_top_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="up-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-go-up</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_up_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="down-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-go-down</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_down_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="bottom-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-goto-bottom</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_bottom_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkAlignment" id="members-buttons-alignment">
<property name="visible">True</property>
<child>
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.c b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
index 212b87f891..31709bcf06 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
@@ -74,6 +74,14 @@
CONTACT_LIST_EDITOR_WIDGET ((editor), "source-combo-box")
#define CONTACT_LIST_EDITOR_WIDGET_TREE_VIEW(editor) \
CONTACT_LIST_EDITOR_WIDGET ((editor), "tree-view")
+#define CONTACT_LIST_EDITOR_WIDGET_TOP_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "top-button")
+#define CONTACT_LIST_EDITOR_WIDGET_UP_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "up-button")
+#define CONTACT_LIST_EDITOR_WIDGET_DOWN_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "down-button")
+#define CONTACT_LIST_EDITOR_WIDGET_BOTTOM_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "bottom-button")
/* Shorthand, requires a variable named "editor". */
#define WIDGET(name) (CONTACT_LIST_EDITOR_WIDGET_##name (editor))
@@ -355,6 +363,53 @@ contact_list_editor_row_inserted_cb (GtkTreeModel *model,
gtk_widget_set_sensitive (WIDGET (REMOVE_BUTTON), TRUE);
}
+static void
+contact_list_editor_selection_changed_cb (GtkTreeSelection *selection,
+ gpointer user_data)
+{
+ EContactListEditor *editor = user_data;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *first_item;
+ GList *selected;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+
+ /* Is selected anything at all? */
+ if (gtk_tree_selection_count_selected_rows (selection) == 0) {
+ gtk_widget_set_sensitive (WIDGET (TOP_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (UP_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (DOWN_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (BOTTOM_BUTTON), FALSE);
+ return;
+ }
+
+ /* Item before selected item exists => enable Top/Up buttons */
+ selected = gtk_tree_selection_get_selected_rows (selection, &model);
+ first_item = gtk_tree_path_copy (selected->data); /* Don't update path in the list! */
+ if (gtk_tree_path_prev (first_item)) {
+ gtk_widget_set_sensitive (WIDGET (TOP_BUTTON), TRUE);
+ gtk_widget_set_sensitive (WIDGET (UP_BUTTON), TRUE);
+ } else {
+ gtk_widget_set_sensitive (WIDGET (TOP_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (UP_BUTTON), FALSE);
+ }
+
+ gtk_tree_model_get_iter (model, &iter, g_list_last (selected)->data);
+ /* Item below last selected exists => enable Down/Bottom buttons */
+ if (gtk_tree_model_iter_next (model, &iter)) {
+ gtk_widget_set_sensitive (WIDGET (DOWN_BUTTON), TRUE);
+ gtk_widget_set_sensitive (WIDGET (BOTTOM_BUTTON), TRUE);
+ } else {
+ gtk_widget_set_sensitive (WIDGET (DOWN_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (BOTTOM_BUTTON), FALSE);
+ }
+
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (selected);
+ gtk_tree_path_free (first_item);
+}
+
/*********************** Autoconnected Signal Handlers ***********************/
void
@@ -698,9 +753,11 @@ contact_list_editor_remove_button_clicked_cb (GtkWidget *widget)
{
EContactListEditor *editor;
GtkTreeSelection *selection;
+ GtkTreeRowReference *new_selection;
GtkTreeModel *model;
GtkTreeView *view;
- GList *list, *iter;
+ GtkTreePath *path;
+ GList *list, *liter;
editor = contact_list_editor_extract (widget);
@@ -709,17 +766,23 @@ contact_list_editor_remove_button_clicked_cb (GtkWidget *widget)
list = gtk_tree_selection_get_selected_rows (selection, &model);
/* Convert the GtkTreePaths to GtkTreeRowReferences. */
- for (iter = list; iter != NULL; iter = iter->next) {
- GtkTreePath *path = iter->data;
+ for (liter = list; liter != NULL; liter = liter->next) {
+ path = liter->data;
+
+ liter->data = gtk_tree_row_reference_new (model, path);
+
+ /* Store reference to next item below current selection */
+ if (!liter->next) {
+ gtk_tree_path_next (path);
+ new_selection = gtk_tree_row_reference_new (model, path);
+ }
- iter->data = gtk_tree_row_reference_new (model, path);
gtk_tree_path_free (path);
}
/* Delete each row in the list. */
- for (iter = list; iter != NULL; iter = iter->next) {
- GtkTreeRowReference *reference = iter->data;
- GtkTreePath *path;
+ for (liter = list; liter != NULL; liter = liter->next) {
+ GtkTreeRowReference *reference = liter->data;
GtkTreeIter iter;
gboolean valid;
@@ -732,6 +795,29 @@ contact_list_editor_remove_button_clicked_cb (GtkWidget *widget)
gtk_tree_row_reference_free (reference);
}
+ /* new_selection != NULL when there is at least one item below the
+ removed selection */
+ if (new_selection) {
+ path = gtk_tree_row_reference_get_path (new_selection);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+ gtk_tree_row_reference_free (new_selection);
+ } else {
+ /* If selection was including the last item in the list, then
+ find and select the new last item */
+ GtkTreeIter iter, iter2;
+
+ /* When FALSE is returned, there are no items in the list to be selected */
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ iter2 = iter;
+
+ while (gtk_tree_model_iter_next (model, &iter))
+ iter2 = iter;
+
+ gtk_tree_selection_select_iter (selection, &iter2);
+ }
+ }
+
g_list_free (list);
editor->priv->changed = TRUE;
@@ -842,6 +928,131 @@ contact_list_editor_tree_view_key_press_event_cb (GtkWidget *widget,
return FALSE;
}
+void
+contact_list_editor_top_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_top_button_clicked_cb (GtkButton *button)
+{
+ EContactListEditor *editor = contact_list_editor_extract (GTK_WIDGET (button));
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GList *references = NULL;
+
+ GList *l, *selected = gtk_tree_selection_get_selected_rows (selection, &model);
+ for (l = selected; l; l = l->next)
+ references = g_list_prepend (references, gtk_tree_row_reference_new (model, l->data));
+
+ for (l = references; l; l = l->next) {
+ path = gtk_tree_row_reference_get_path (l->data);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_list_store_move_after (GTK_LIST_STORE (model), &iter, NULL);
+ gtk_tree_path_free (path);
+ }
+
+ g_list_foreach (references, (GFunc) gtk_tree_row_reference_free, NULL);
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (references);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
+}
+
+void
+contact_list_editor_up_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_up_button_clicked_cb (GtkButton *button)
+{
+ EContactListEditor *editor = contact_list_editor_extract (GTK_WIDGET (button));
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeIter iter, iter2;
+ GtkTreePath *path;
+
+ GList *selected = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ /* Get iter of item above the first selected item */
+ path = gtk_tree_path_copy (selected->data);
+ gtk_tree_path_prev (path);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+
+ /* Get iter of the last selected item */
+ gtk_tree_model_get_iter (model, &iter2, g_list_last (selected)->data);
+
+ gtk_list_store_move_after (GTK_LIST_STORE (model), &iter, &iter2);
+
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
+}
+
+void
+contact_list_editor_down_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_down_button_clicked_cb (GtkButton *button)
+{
+ EContactListEditor *editor = contact_list_editor_extract (GTK_WIDGET (button));
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeIter iter, iter2;
+
+ GList *selected = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ /* Iter of the first selected item */
+ gtk_tree_model_get_iter (model, &iter, selected->data);
+
+ /* Iter of item below the last selected item */
+ gtk_tree_model_get_iter (model, &iter2, g_list_last (selected)->data);
+ gtk_tree_model_iter_next (model, &iter2);
+
+ gtk_list_store_move_before (GTK_LIST_STORE (model), &iter2, &iter);
+
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
+}
+
+void
+contact_list_editor_bottom_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_bottom_button_clicked_cb (GtkButton *button)
+{
+ EContactListEditor *editor = contact_list_editor_extract (GTK_WIDGET (button));
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GList *references = NULL;
+
+ GList *l, *selected = gtk_tree_selection_get_selected_rows (selection, &model);
+ for (l = selected; l; l = l->next)
+ references = g_list_prepend (references, gtk_tree_row_reference_new (model, l->data));
+ references = g_list_reverse (references);
+
+ for (l = references; l; l = l->next) {
+ path = gtk_tree_row_reference_get_path (l->data);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_list_store_move_before (GTK_LIST_STORE (model), &iter, NULL);
+ gtk_tree_path_free (path);
+ }
+
+ g_list_foreach (references, (GFunc) gtk_tree_row_reference_free, NULL);
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (references);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
+}
+
+
/******************** GtkBuilder Custom Widgets Functions ********************/
static gpointer
@@ -1277,6 +1488,7 @@ contact_list_editor_init (EContactListEditor *editor)
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeView *view;
+ GtkTreeSelection *selection;
editor->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (
editor, E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorPrivate);
@@ -1297,8 +1509,10 @@ contact_list_editor_init (EContactListEditor *editor)
priv->model = e_contact_list_model_new ();
gtk_tree_view_set_model (view, priv->model);
- gtk_tree_selection_set_mode (
- gtk_tree_view_get_selection (view), GTK_SELECTION_MULTIPLE);
+ selection = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (selection, "changed",
+ G_CALLBACK (contact_list_editor_selection_changed_cb), editor);
gtk_tree_view_enable_model_drag_dest (view, NULL, 0, GDK_ACTION_LINK);
e_drag_dest_add_directory_targets (WIDGET (TREE_VIEW));