k.add :forward, "Forward latest message in a thread", 'f'
k.add :toggle_tagged, "Tag/untag selected thread", 't'
k.add :toggle_tagged_all, "Tag/untag all threads", 'T'
+ k.add :tag_matching, "Tag matching threads", 'g'
k.add :apply_to_tagged, "Apply next command to all tagged threads", ';'
end
## are set, and the second to show the cursor having moved
update_text_for_line curpos
- UpdateManager.relay self, :read, t
+ UpdateManager.relay self, :read, t.first
end
end
threads.each { |t| select t }
end
- def handle_label_update sender, m
- t = @ts_mutex.synchronize { @ts.thread_for(m) } or return
- handle_label_thread_update sender, t
- end
-
- def handle_label_thread_update sender, t
- l = @lines[t] or return
- update_text_for_line l
- BufferManager.draw_screen
+ def handle_single_message_labeled_update sender, m
+ ## no need to do anything different here; we don't differentiate
+ ## messages from their containing threads
+ handle_labeled_update sender, m
+ end
+
+ def handle_labeled_update sender, m
+ if(t = thread_containing(m))
+ l = @lines[t] or return
+ update_text_for_line l
+ elsif is_relevant?(m)
+ add_or_unhide m
+ end
end
- def handle_read_update sender, t
+ def handle_read_update sender, m
+ t = thread_containing(m) or return
l = @lines[t] or return
update_text_for_line l
- BufferManager.draw_screen
end
def handle_archived_update *a; handle_read_update(*a); end
- def handle_deleted_update sender, t
- handle_read_update sender, t
+ def handle_deleted_update sender, m
+ t = thread_containing(m) or return
hide_thread t
regen_text
end
## overwrite me!
def is_relevant? m; false; end
- def handle_add_update sender, m
- @ts_mutex.synchronize do
- return unless is_relevant?(m) || @ts.is_relevant?(m)
- @ts.load_thread_for_message m
- end
- update
+ def handle_added_update sender, m
+ add_or_unhide m
BufferManager.draw_screen
end
- def handle_delete_update sender, mid
+ def handle_deleted_update sender, m
@ts_mutex.synchronize do
- return unless @ts.contains_id? mid
- @ts.remove mid
+ return unless @ts.contains? m
+ @ts.remove_id m.id
end
update
- BufferManager.draw_screen
+ end
+
+ def handle_undeleted_update sender, m
+ add_or_unhide m
end
def update
def actually_toggle_starred t
if t.has_label? :starred # if ANY message has a star
t.remove_label :starred # remove from all
- UpdateManager.relay self, :unstarred, t
+ UpdateManager.relay self, :unstarred, t.first
else
t.first.add_label :starred # add only to first
- UpdateManager.relay self, :starred, t
+ UpdateManager.relay self, :starred, t.first
end
end
def actually_toggle_archived t
if t.has_label? :inbox
t.remove_label :inbox
- UpdateManager.relay self, :archived, t
+ UpdateManager.relay self, :archived, t.first
else
t.apply_label :inbox
- UpdateManager.relay self, :unarchived, t
+ UpdateManager.relay self, :unarchived, t.first
end
end
def actually_toggle_spammed t
if t.has_label? :spam
t.remove_label :spam
- UpdateManager.relay self, :unspammed, t
+ UpdateManager.relay self, :unspammed, t.first
else
t.apply_label :spam
- UpdateManager.relay self, :spammed, t
+ UpdateManager.relay self, :spammed, t.first
end
end
def actually_toggle_deleted t
if t.has_label? :deleted
t.remove_label :deleted
- UpdateManager.relay self, :undeleted, t
+ UpdateManager.relay self, :undeleted, t.first
else
t.apply_label :deleted
- UpdateManager.relay self, :deleted, t
+ UpdateManager.relay self, :deleted, t.first
end
end
regen_text
end
+ def tag_matching
+ query = BufferManager.ask :search, "tag threads matching: "
+ return if query.nil? || query.empty?
+ query = /#{query}/i
+ @mutex.synchronize { @threads.each { |t| @tags.tag t if thread_matches?(t, query) } }
+ regen_text
+ end
+
def apply_to_tagged; @tags.apply_to_tagged; end
def edit_labels
return unless user_labels
thread.labels = keepl + user_labels
user_labels.each { |l| LabelManager << l }
- update_text_for_line curpos
+ UpdateManager.relay self, :labeled, thread.first
end
def multi_edit_labels threads
m = t.latest_message
return if m.nil? # probably won't happen
m.load_from_source!
- ForwardMode.spawn_nicely m
+ ForwardMode.spawn_nicely :message => m
end
def load_n_threads_background n=LOAD_MORE_THREAD_NUM, opts={}
protected
+ def add_or_unhide m
+ if @hidden_threads[m]
+ @hidden_threads.delete m
+ ## now it will re-appear when #update is called
+ else
+ @ts_mutex.synchronize do
+ return unless is_relevant?(m) || @ts.is_relevant?(m)
+ @ts.load_thread_for_message m
+ end
+ end
+
+ update
+ end
+
+ def thread_containing m; @ts_mutex.synchronize { @ts.thread_for m } end
+
+ ## used to tag threads by query. this can be made a lot more sophisticated,
+ ## but for right now we'll do the obvious this.
+ def thread_matches? t, query
+ t.subj =~ query || t.snippet =~ query || t.participants.any? { |x| x.longname =~ query }
+ end
+
def size_widget_for_thread t
HookManager.run("index-mode-size-widget", :thread => t) || default_size_widget_for(t)
end