[Xfce4-commits] <postler:master> Move actions into action bar, check via check box
Christian Dywan
noreply at xfce.org
Sun Jul 17 05:34:04 CEST 2011
Updating branch refs/heads/master
to cf5c974efe2a641efa76090d9ac14f3fe3fdacc5 (commit)
from 373a0c661e31c465957c70f509502189607edc41 (commit)
commit cf5c974efe2a641efa76090d9ac14f3fe3fdacc5
Author: Christian Dywan <christian at twotoasts.de>
Date: Sun Jul 17 01:26:29 2011 +0200
Move actions into action bar, check via check box
postler/postler-bureau.vala | 85 +++++++++++++++++-------
postler/postler-cellrenderertoggle.vala | 16 +++++
postler/postler-messages.vala | 110 ++++++++++++++++++++++--------
3 files changed, 157 insertions(+), 54 deletions(-)
diff --git a/postler/postler-bureau.vala b/postler/postler-bureau.vala
index 294bcc2..f46e397 100644
--- a/postler/postler-bureau.vala
+++ b/postler/postler-bureau.vala
@@ -20,6 +20,7 @@ public class Postler.Bureau : Gtk.Window {
Gtk.VBox shelf;
Gtk.Toolbar toolbar;
+ Gtk.Toolbar message_actions;
Elementary.SearchEntry search;
Gtk.Toolbar search_options;
uint search_timeout = 0;
@@ -54,6 +55,7 @@ public class Postler.Bureau : Gtk.Window {
<menuitem action="MessageArchive"/>
<menuitem action="MessageJunk"/>
<menuitem action="MessageDelete"/>
+ <menuitem action="CheckedCancel"/>
<separator/>
<menuitem action="MessageNextUnread"/>
<menuitem action="MessagePreviousUnread"/>
@@ -78,9 +80,6 @@ public class Postler.Bureau : Gtk.Window {
<toolitem action="MessageNew"/>
<separator/>
<toolitem action="MessageReplyAll"/>
- <toolitem action="MessageArchive"/>
- <toolitem action="MessageJunk"/>
- <toolitem action="MessageDelete"/>
<separator expand="true"/>
</toolbar>
<popup name="view">
@@ -90,6 +89,13 @@ public class Postler.Bureau : Gtk.Window {
<menuitem action="Shortcuts"/>
<menuitem action="About"/>
</popup>
+ <toolbar name="message_actions">
+ <toolitem action="MessageArchive"/>
+ <toolitem action="MessageJunk"/>
+ <toolitem action="MessageDelete"/>
+ <separator expand="true"/>
+ <toolitem action="CheckedCancel"/>
+ </toolbar>
<toolbar name="search_options">
<toolitem action="SearchAny"/>
<toolitem action="SearchSubject"/>
@@ -137,20 +143,24 @@ public class Postler.Bureau : Gtk.Window {
void action_archive () {
if (messages.selected_folder_type != FolderType.ARCHIVE)
- messages.move_selected (FolderType.ARCHIVE);
+ messages.move_checked (FolderType.ARCHIVE);
else
- messages.move_selected (FolderType.INBOX);
+ messages.move_checked (FolderType.INBOX);
}
void action_junk () {
if (messages.selected_folder_type != FolderType.JUNK)
- messages.move_selected (FolderType.JUNK);
+ messages.move_checked (FolderType.JUNK);
else
- messages.move_selected (FolderType.INBOX);
+ messages.move_checked (FolderType.INBOX);
}
void action_delete () {
- messages.delete_selected ();
+ messages.delete_checked ();
+ }
+
+ void action_checked_cancel () {
+ messages.uncheck_all ();
}
void action_previous_unread () {
@@ -184,10 +194,14 @@ public class Postler.Bureau : Gtk.Window {
assert_not_reached ();
}
+ void context_bar_toggle (Gtk.Widget current) {
+ folders.visible = search_options.visible = message_actions.visible = false;
+ current.show ();
+ }
+
void search_apply () {
if (search.get_text () == search.hint_string || search.get_text ().strip () == "") {
- search_options.hide ();
- folders.show ();
+ context_bar_toggle (folders);
var action = actions.get_action ("SearchSubject") as Gtk.RadioAction;
action.set_current_value (0);
messages.populate (folders.selected_location);
@@ -195,8 +209,7 @@ public class Postler.Bureau : Gtk.Window {
}
messages.populate (get_search_uri ());
- folders.hide ();
- search_options.show ();
+ context_bar_toggle (search_options);
}
void action_save_search () {
@@ -354,6 +367,8 @@ public class Postler.Bureau : Gtk.Window {
N_("Mark message as junk"), action_junk },
{ "MessageDelete", Gtk.STOCK_DELETE, null, "<Ctrl>d",
N_("Delete message"), action_delete },
+ { "CheckedCancel", Gtk.STOCK_CANCEL, null, "Escape",
+ N_("Cancel operation on messages"), action_checked_cancel },
{ "MessagePreviousUnread", null, N_("_Previous Unread Message"), "<Alt>Up",
N_("Go to the previous unread message"), action_previous_unread },
{ "MessageNextUnread", null, N_("_Next Unread Message"), "<Alt>Down",
@@ -434,7 +449,7 @@ public class Postler.Bureau : Gtk.Window {
infobar.response.connect ((response) => {
switch (response) {
case 1:
- messages.move_selected (FolderType.INBOX);
+ messages.move_checked (FolderType.INBOX);
break;
case 2:
folders.empty_folder (messages.location);
@@ -444,15 +459,15 @@ public class Postler.Bureau : Gtk.Window {
assert_not_reached ();
}
});
- messages.notify["selected-message"].connect ((object, pspec) => {
+ messages.notify["checked-messages"].connect ((object, pspec) => {
infobar.set_response_sensitive (1,
- messages.get_selection ().count_selected_rows () > 0);
+ messages.checked_messages.nth_data (0) != null);
});
trash_action_infobar = infobar;
}
trash_action_infobar.set_response_sensitive (1,
- messages.get_selection ().count_selected_rows () > 0);
+ messages.checked_messages.nth_data (0) != null);
trash_action_infobar.show ();
}
@@ -713,6 +728,22 @@ public class Postler.Bureau : Gtk.Window {
trash_action_infobar.hide ();
});
+ message_actions = ui.get_widget ("/message_actions") as Gtk.Toolbar;
+ message_actions.icon_size = Gtk.IconSize.SMALL_TOOLBAR;
+ #if HAVE_GTK3
+ message_actions.get_style_context ().add_class ("secondary-toolbar");
+ #endif
+ /* Implement mnemonics for search buttons */
+ foreach (var button in message_actions.get_children ()) {
+ if (button is Gtk.ToolButton) {
+ var toolbutton = button as Gtk.ToolButton;
+ toolbutton.is_important = true;
+ var label = new Gtk.Label.with_mnemonic (toolbutton.label);
+ toolbutton.label_widget = label;
+ }
+ }
+ shelf.pack_start (message_actions, false, false, 0);
+
search_options = ui.get_widget ("/search_options") as Gtk.Toolbar;
#if HAVE_GTK3
search_options.get_style_context ().add_class ("secondary-toolbar");
@@ -744,11 +775,19 @@ public class Postler.Bureau : Gtk.Window {
Postler.Messages messages = object as Postler.Messages;
bool state = messages.selected_message != null;
actions.get_action ("MessageFlag").sensitive = state;
+ });
+ messages.notify["checked-messages"].connect ((object, pspec) => {
+ Postler.Messages messages = object as Postler.Messages;
+ bool state = messages.checked_messages.nth_data (0) != null;
actions.get_action ("MessageArchive").sensitive = state;
- var action = actions.get_action ("MessageJunk");
- action.sensitive = state;
- action = actions.get_action ("MessageDelete");
- action.sensitive = state;
+ actions.get_action ("MessageJunk").sensitive = state;
+ actions.get_action ("MessageDelete").sensitive = state;
+ if (state)
+ context_bar_toggle (message_actions);
+ else if (search.get_text () == search.hint_string || search.get_text ().strip () == "")
+ context_bar_toggle (folders);
+ else
+ context_bar_toggle (search_options);
});
var scrolled = new Postler.ScrolledWindow (messages);
messages_box.pack_start (scrolled, true, true, 0);
@@ -876,7 +915,6 @@ public class Postler.Bureau : Gtk.Window {
return false;
});
shelf.show_all ();
- search_options.hide ();
messages.set_headers_visible (false);
messages.set_rules_hint (true);
@@ -889,11 +927,10 @@ public class Postler.Bureau : Gtk.Window {
accounts.remove_info.connect_after (account_check);
account_check (null);
+ folders.select_folder ("file://%/INBOX/%");
/* Never focus hidden widgets: assertion `WIDGET_REALIZED_FOR_EVENT */
- if (messages.visible) {
+ if (messages.visible)
messages.grab_focus ();
- folders.select_folder ("file://%/INBOX/%");
- }
if (Environment.get_variable ("POSTLER_MOCKUP") != null) {
progressbar.fraction = 0.7;
diff --git a/postler/postler-cellrenderertoggle.vala b/postler/postler-cellrenderertoggle.vala
index 1e37e8a..a8ec3d8 100644
--- a/postler/postler-cellrenderertoggle.vala
+++ b/postler/postler-cellrenderertoggle.vala
@@ -15,9 +15,15 @@ public class Postler.CellRendererToggle : Gtk.CellRendererToggle {
public CellRendererToggle () {
}
+
public override void get_size (Gtk.Widget widget, Gdk.Rectangle? cell_area,
out int x_offset, out int y_offset, out int width, out int height) {
+ if (prelight_stock_id == null && stock_id == null) {
+ base.get_size (widget, cell_area, out x_offset, out y_offset, out width, out height);
+ return;
+ }
+
int icon_width, icon_height;
int xpad, ypad;
Gtk.icon_size_lookup_for_settings (widget.get_settings (),
@@ -55,11 +61,21 @@ public class Postler.CellRendererToggle : Gtk.CellRendererToggle {
Gdk.Rectangle expose_area, Gdk.Rectangle cell_area,
Gtk.CellRendererState flags) {
Gdk.Rectangle background_area = expose_area;
+
+ if (prelight_stock_id == null && stock_id == null) {
+ base.render (context, widget, expose_area, cell_area, flags);
+ return;
+ }
#else
public override void render (Gdk.Window window, Gtk.Widget widget,
Gdk.Rectangle background_area, Gdk.Rectangle cell_area,
Gdk.Rectangle expose_area, Gtk.CellRendererState flags) {
var context = Gdk.cairo_create (window);
+
+ if (prelight_stock_id == null && stock_id == null) {
+ base.render (window, widget, background_area, cell_area, expose_area, flags);
+ return;
+ }
#endif
Gdk.cairo_rectangle (context, expose_area);
diff --git a/postler/postler-messages.vala b/postler/postler-messages.vala
index 4ac847b..7e23168 100644
--- a/postler/postler-messages.vala
+++ b/postler/postler-messages.vala
@@ -20,6 +20,7 @@ public class Postler.Messages : Gtk.TreeView {
public FolderType selected_folder_type { get; private set; }
public string? location { get; private set; }
public Message? selected_message { get; private set; }
+ public unowned GLib.List<Message>? checked_messages { get; private set; }
enum Columns {
MESSAGE
@@ -54,6 +55,14 @@ public class Postler.Messages : Gtk.TreeView {
return fallback.str;
}
+ void render_checkbox (Gtk.CellLayout layout, Gtk.CellRenderer cell,
+ Gtk.TreeModel model, Gtk.TreeIter iter) {
+
+ Message message;
+ model.get (iter, Columns.MESSAGE, out message);
+ cell.set ("active", message.get_data<bool> ("checked"));
+ }
+
void render_flag (Gtk.CellLayout layout, Gtk.CellRenderer cell,
Gtk.TreeModel model, Gtk.TreeIter iter) {
Message message;
@@ -110,6 +119,27 @@ public class Postler.Messages : Gtk.TreeView {
renderer.text = message.excerpt + "…";
}
+ void renderer_checkbox_toggled (Gtk.CellRendererToggle renderer,
+ string path) {
+ Gtk.TreeIter iter = Gtk.TreeIter ();
+ if (!model.get_iter_from_string (out iter, path))
+ return;
+
+ Message message;
+ model.get (iter, Columns.MESSAGE, out message);
+ if (message.get_data<bool> ("checked")) {
+ checked_messages.remove (message);
+ message.set_data ("checked", false);
+ }
+ else {
+ checked_messages.append (message);
+ message.set_data ("checked", true);
+ message.set_data ("row", new Gtk.TreeRowReference (
+ model, model.get_path (iter)));
+ }
+ notify_property ("checked-messages");
+ }
+
void renderer_flag_toggled (Gtk.CellRendererToggle renderer,
string path) {
Gtk.TreeIter iter = Gtk.TreeIter ();
@@ -151,13 +181,25 @@ public class Postler.Messages : Gtk.TreeView {
var column = new Gtk.TreeViewColumn ();
column.set_sizing (Gtk.TreeViewColumnSizing.FIXED);
+ column.set_title (_("Selected"));
+ var renderer_checkbox = new Postler.CellRendererToggle ();
+ column.pack_start (renderer_checkbox, true);
+ column.set_cell_data_func (renderer_checkbox, render_checkbox);
+ renderer_checkbox.toggled.connect (renderer_checkbox_toggled);
+ insert_column (column, -1);
+ int cell_width, xpad;
+ column.cell_get_size (null, null, null, out cell_width, null);
+ Gtk.cell_renderer_get_padding (renderer_checkbox, out xpad, null);
+ column.set_fixed_width (cell_width + xpad * 4);
+
+ column = new Gtk.TreeViewColumn ();
+ column.set_sizing (Gtk.TreeViewColumnSizing.FIXED);
column.set_title (_("Flagged"));
var renderer_flag = new Postler.CellRendererToggle ();
column.pack_start (renderer_flag, true);
column.set_cell_data_func (renderer_flag, render_flag);
renderer_flag.toggled.connect (renderer_flag_toggled);
insert_column (column, -1);
- int cell_width, xpad;
column.cell_get_size (null, null, null, out cell_width, null);
Gtk.cell_renderer_get_padding (renderer_flag, out xpad, null);
column.set_fixed_width (cell_width + xpad * 4);
@@ -224,7 +266,7 @@ public class Postler.Messages : Gtk.TreeView {
}
[Signal (action=true)]
public virtual signal void delete () {
- delete_selected ();
+ delete_checked ();
}
static string decode_piece (string encoded, out string charset) {
@@ -294,9 +336,23 @@ public class Postler.Messages : Gtk.TreeView {
return fallback_to_utf8 (decoded.str);
}
+ public void uncheck_all () {
+ foreach (var message in checked_messages) {
+ message.set_data<bool> ("checked", false);
+ var reference = message.get_data<Gtk.TreeRowReference> ("row");
+ Gtk.TreePath? path = reference.get_path ();
+ Gtk.TreeIter iter;
+ if (reference.get_model ().get_iter (out iter, path))
+ reference.get_model ().row_changed (path, iter);
+ }
+ checked_messages = new GLib.List<Message> ();
+ notify_property ("checked-messages");
+ }
+
public void clear () {
client = null;
store.clear ();
+ uncheck_all ();
}
static string flags_from_filename (string filename, out string bare_filename) {
@@ -497,13 +553,6 @@ public class Postler.Messages : Gtk.TreeView {
return true;
}
- public void delete_selected () {
- if (selected_folder_type == FolderType.TRASH)
- move_selected (null);
- else
- move_selected (FolderType.TRASH);
- }
-
public static uint32 obtain_uid_sequence (string folder, uint32 fallback_sequence) {
/* Update .uidvalidity number, also read and updated by mbsync */
uint32 uid_sequence = fallback_sequence;
@@ -563,26 +612,17 @@ public class Postler.Messages : Gtk.TreeView {
return new_folder + parts[0] + ",U=" + uid_sequence.to_string () + ":2," + parts[2];
}
- public void move_selected (FolderType? type) {
- string? destination_path;
- if (type == null)
- destination_path = null;
+ public void delete_checked () {
+ if (selected_folder_type == FolderType.TRASH)
+ move_checked (null);
else
- destination_path = "/"; /* Nonsense path, in case of later errors */
-
- GLib.List<Gtk.TreePath> paths;
- var references = new GLib.List<Gtk.TreeRowReference> ();
- paths = get_selection ().get_selected_rows (null);
- foreach (var path in paths)
- references.prepend (new Gtk.TreeRowReference (model, path));
+ move_checked (FolderType.TRASH);
+ }
- foreach (var reference in references) {
- var path = reference.get_path ();
- Gtk.TreeIter iter;
- if (model.get_iter (out iter, path)) {
- Message message;
- model.get (iter, Columns.MESSAGE, out message);
- try {
+ public void move_checked (FolderType? type) {
+ foreach (var message in checked_messages) {
+ string? destination_path = null;
+ if (type != null) {
AccountInfo account_info = message.get_account (accounts);
return_if_fail (account_info != null);
string? folder_name = null;
@@ -594,8 +634,17 @@ public class Postler.Messages : Gtk.TreeView {
}
destination_path = account_info.path + "/" + folder_name;
return_if_fail (destination_path != null);
+ }
+ try {
message.move (destination_path);
-
+ /* Remove iter, move on to next row */
+ var reference = message.get_data<Gtk.TreeRowReference> ("row");
+ var path = reference.get_path ();
+ Gtk.TreeIter iter;
+ if (!model.get_iter (out iter, path)) {
+ message.from_error ("Message moved: No valid iter");
+ continue;
+ }
/* Move to next, more recent message row */
Gtk.TreePath next_path = model.get_path (iter);
content.clear ();
@@ -612,9 +661,10 @@ public class Postler.Messages : Gtk.TreeView {
warning = _("Failed to delete message \"%s\": %s");
else
warning = _("Failed to move message \"%s\": %s");
- GLib.critical (warning, location, error.message);
+ GLib.critical (warning, message.uri, error.message);
}
- }
+ checked_messages.remove (message);
+ message.set_data<bool> ("checked", false);
}
}
More information about the Xfce4-commits
mailing list