end
## not really a good place for this, so I'll just dump it here.
- def report_broken_sources
+ def report_broken_sources opts={}
return unless BufferManager.instantiated?
broken_sources = Index.usual_sources.select { |s| s.error.is_a? FatalSourceError }
unless broken_sources.empty?
- BufferManager.spawn "Broken source notification", TextMode.new(<<EOM)
+ BufferManager.spawn "Broken source notification", TextMode.new(<<EOM), opts
Source error notification
-------------------------
desynced_sources = Index.usual_sources.select { |s| s.error.is_a? OutOfSyncSourceError }
unless desynced_sources.empty?
- BufferManager.spawn("Out-of-sync source notification", TextMode.new(<<EOM))
+ BufferManager.spawn "Out-of-sync source notification", TextMode.new(<<EOM), opts
Out-of-sync source notification
-------------------------------
class Buffer
attr_reader :mode, :x, :y, :width, :height, :title
bool_reader :dirty
+ bool_accessor :force_to_top
def initialize window, mode, width, height, opts={}
@w = window
@dirty = true
@focus = false
@title = opts[:title] || ""
+ @force_to_top = opts[:force_to_top] || false
@x, @y, @width, @height = 0, 0, width, height
end
def raise_to_front buf
raise ArgumentError, "buffer not on stack: #{buf.inspect}" unless @buffers.member? buf
+
@buffers.delete buf
- @buffers.push buf
- focus_on buf
+ if @buffers.length > 0 && @buffers.last.force_to_top?
+ @buffers.insert -2, buf
+ else
+ @buffers.push buf
+ focus_on buf
+ end
@dirty = true
end
+ ## we reset force_to_top when rolling buffers. this is so that the
+ ## human can actually still move buffers around, while still
+ ## programmatically being able to pop stuff up in the middle of
+ ## drawing a window without worrying about covering it up.
+ ##
+ ## if we ever start calling roll_buffers programmatically, we will
+ ## have to change this. but it's not clear that we will ever actually
+ ## do that.
def roll_buffers
+ @buffers.last.force_to_top = false
raise_to_front @buffers.first
end
def roll_buffers_backwards
return unless @buffers.length > 1
+ @buffers.last.force_to_top = false
raise_to_front @buffers[@buffers.length - 2]
end
## w = Ncurses::WINDOW.new(height, width, (opts[:top] || 0),
## (opts[:left] || 0))
w = Ncurses.stdscr
- b = Buffer.new w, mode, width, height, :title => realtitle
+ b = Buffer.new w, mode, width, height, :title => realtitle, :force_to_top => (opts[:force_to_top] || false)
mode.buffer = b
@name_map[realtitle] = b
+
+ @buffers.unshift b
if opts[:hidden]
- @buffers.unshift b
focus_on b unless @focus_buf
else
- @buffers.push b
raise_to_front b
end
b
end
def ssl?; @parsed_uri.scheme == 'imaps' end
- def check; scan_mailbox; end
+ def check
+ ids =
+ @mutex.synchronize do
+ unsynchronized_scan_mailbox
+ @ids
+ end
+
+ start = ids.index(cur_offset || start_offset) or raise OutOfSyncSourceError, "Unknown message id #{cur_offset || start_offset}."
+ end
## is this necessary? TODO: remove maybe
def == o; o.is_a?(IMAP) && o.uri == self.uri && o.username == self.username; end
read_header @source.load_header(@source_info)
message_to_chunks @source.load_message(@source_info)
rescue SourceError, SocketError, MessageFormatError => e
+ ## we need force_to_top here otherwise this window will cover
+ ## up the error message one
+ Redwood::report_broken_sources :force_to_top => true
[Text.new(error_message(e.message))]
end
end