Bug #229244 - Re-ordering email addresses in contact list editor

This commit is contained in:
Dan Vrátil
2011-05-27 19:13:45 +02:00
committed by Rodrigo Moya
parent c24038c4f6
commit 3f67582bbd
2 changed files with 293 additions and 9 deletions

View File

@ -257,6 +257,76 @@
<property name="position">2</property>
</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>

View File

@ -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));