class Rabbit::Canvas

Constants

INTERNAL_DPI

Attributes

actions[R]
allotted_time[W]
comment_theme[RW]
comments[R]
font_resolution_ratio[RW]
last_modified[R]
logger[R]
max_n_comments[RW]
migemo_dictionary_name[RW]
migemo_dictionary_search_path[RW]
output_html[RW]
output_index_html[RW]
renderer[R]
rss_base_uri[RW]
saved_image_base_name[W]
saved_image_type[RW]
source_filename[RW]
use_gl[W]

Public Class Methods

new(logger, renderer) click to toggle source
# File lib/rabbit/canvas.rb, line 159
def initialize(logger, renderer)
  @logger = logger
  @frame = NullFrame.new
  @theme_name = nil
  @saved_image_base_name = nil
  @saved_image_type = "png"
  @processing = false
  @quitted = false
  @parse_request_queue = []
  @apply_theme_request_queue = []
  @auto_redraw_timer = nil
  @output_html = false
  @rss_base_uri = nil
  @source_filename = nil
  @migemo_dictionary_search_path = []
  @migemo_dictionary_name = nil
  @limit_time = nil
  @use_gl = false
  @font_resolution_ratio = 1
  @max_n_comments = 100
  @allotted_time = nil
  @comment_theme = nil
  clear
  @renderer = renderer.new(self)
  @actions = Action.action_group(self)
end

Public Instance Methods

<<(slide) click to toggle source
# File lib/rabbit/canvas.rb, line 325
def <<(slide)
  slide.index = slides.size
  slides << slide
end
action(name) click to toggle source
# File lib/rabbit/canvas.rb, line 641
def action(name)
  act = @actions.get_action(name)
  if act
    act
  else
    logger.warn(_("Unknown action: %s") % name)
    false
  end
end
activate(name, &block) click to toggle source
# File lib/rabbit/canvas.rb, line 631
def activate(name, &block)
  act = action(name)
  if act and act.sensitive?
    act.activate(&block)
    true
  else
    false
  end
end
allotted_time() click to toggle source
# File lib/rabbit/canvas.rb, line 660
def allotted_time
  time = @allotted_time
  if time.nil? and title_slide
    time = title_slide.allotted_time
    if time.nil?
      start_time = title_slide.start_time
      end_time = title_slide.end_time
      if start_time and end_time
        start_time = Time.parse(start_time)
        end_time = Time.parse(end_time)
        time = end_time - start_time
      end
    end
  end
  Utils.ensure_time(time)
end
append_comment(comment) click to toggle source
# File lib/rabbit/canvas.rb, line 614
def append_comment(comment)
  @comments << comment
  @comments.shift if @comments.size > @max_n_comments
  @on_comment_callbacks.each do |name, callback|
    begin
      callback.call(comment)
    rescue
      logger.error($!)
    end
  end
  true
end
apply_theme(name=nil, &block) click to toggle source
# File lib/rabbit/canvas.rb, line 330
def apply_theme(name=nil, &block)
  _apply_theme(name, Object.new.__id__, &block)
end
apply_timer() click to toggle source
# File lib/rabbit/canvas.rb, line 689
def apply_timer
  return unless title_slide

  start_time = title_slide.start_time
  end_time = title_slide.end_time
  return if start_time.nil?
  return if end_time.nil?

  start_time = Time.parse(start_time)
  end_time = Time.parse(end_time)
  return unless (start_time..end_time).cover?(Time.now)

  @allotted_time = end_time - start_time
  @limit_time = end_time
end
applying?() click to toggle source
# File lib/rabbit/canvas.rb, line 194
def applying?
  not @apply_theme_request_queue.empty?
end
attach_to(frame, window, container=nil, &block) click to toggle source
# File lib/rabbit/canvas.rb, line 211
def attach_to(frame, window, container=nil, &block)
  @frame = frame if frame
  @renderer.attach_to(window, container, &block) if window
end
cache_all_slides() click to toggle source
# File lib/rabbit/canvas.rb, line 573
def cache_all_slides
  process do
    @renderer.cache_all_slides
  end
end
change_current_index(new_index) { || ... } click to toggle source
# File lib/rabbit/canvas.rb, line 297
def change_current_index(new_index)
  mode = @index_mode
  if mode
    index = @index_current_index
    @index_current_index = new_index
  else
    index = @current_index
    @current_index = new_index
  end
  if 0 <= current_index and current_index < slide_size
    yield
  end
ensure
  if mode
    @index_current_index = index
  else
    @current_index = index
  end
end
current_index() click to toggle source
# File lib/rabbit/canvas.rb, line 289
def current_index
  if @index_mode
    @index_current_index
  else
    @current_index
  end
end
current_slide() click to toggle source
# File lib/rabbit/canvas.rb, line 279
def current_slide
  slide = slides[current_index]
  if slide
    slide
  else
    move_to_first
    slides.first
  end
end
delete_on_comment_proc_by_name(name) click to toggle source
# File lib/rabbit/canvas.rb, line 608
def delete_on_comment_proc_by_name(name)
  @on_comment_callbacks.reject! do |callback_name, callback|
    callback_name == name
  end
end
detach() click to toggle source
# File lib/rabbit/canvas.rb, line 216
def detach
  @frame = NullFrame.new
  @renderer.detach
end
each(&block) click to toggle source
# File lib/rabbit/canvas.rb, line 321
def each(&block)
  slides.each(&block)
end
find_slide(pattern) click to toggle source
# File lib/rabbit/canvas.rb, line 256
def find_slide(pattern)
  slides.find {|slide| slide.match?(pattern)}
end
first_slide?() click to toggle source
# File lib/rabbit/canvas.rb, line 545
def first_slide?
  current_index.zero?
end
font_resolution() click to toggle source
# File lib/rabbit/canvas.rb, line 705
def font_resolution
  INTERNAL_DPI * @font_resolution_ratio
end
front(public_level=nil) click to toggle source
# File lib/rabbit/canvas.rb, line 207
def front(public_level=nil)
  Front.new(self, public_level)
end
full_path(path) click to toggle source
# File lib/rabbit/canvas.rb, line 397
def full_path(path)
  @source and @source.full_path(path)
end
fullscreened() click to toggle source
# File lib/rabbit/canvas.rb, line 431
def fullscreened
  @renderer.post_fullscreen
end
have_next?() click to toggle source
# File lib/rabbit/canvas.rb, line 567
def have_next?
  return true if have_next_slide?
  return !current_slide.last? if current_slide
  false
end
have_next_slide?() click to toggle source
# File lib/rabbit/canvas.rb, line 563
def have_next_slide?
  slide_size - 1 > current_index
end
have_previous?() click to toggle source
# File lib/rabbit/canvas.rb, line 557
def have_previous?
  return true if have_previous_slide?
  return !current_slide.first? if current_slide
  false
end
have_previous_slide?() click to toggle source
# File lib/rabbit/canvas.rb, line 553
def have_previous_slide?
  0 < current_index
end
iconified() click to toggle source
# File lib/rabbit/canvas.rb, line 439
def iconified
  @renderer.post_iconify
end
index_mode?() click to toggle source
# File lib/rabbit/canvas.rb, line 508
def index_mode?
  @index_mode
end
last_slide?() click to toggle source
# File lib/rabbit/canvas.rb, line 549
def last_slide?
  slide_size.zero? or current_index == (slide_size - 1)
end
merge_theme(name) click to toggle source
# File lib/rabbit/canvas.rb, line 338
def merge_theme(name)
  unless @slides.empty?
    manager = Theme::Manager.new(self)
    manager.apply(name)
    @renderer.post_apply_theme
  end
end
move_to_first() click to toggle source
# File lib/rabbit/canvas.rb, line 500
def move_to_first
  move_to_if_can(0)
end
move_to_if_can(index) click to toggle source
# File lib/rabbit/canvas.rb, line 461
def move_to_if_can(index)
  if index and 0 <= index and index < slide_size
    move_to(index)
  end
  current_index
end
move_to_last() click to toggle source
# File lib/rabbit/canvas.rb, line 504
def move_to_last
  move_to(slide_size - 1)
end
move_to_next_if_can() click to toggle source
# File lib/rabbit/canvas.rb, line 468
def move_to_next_if_can
  slide = current_slide
  if slide and !slide.last?
    old_index = slide.drawing_index
    slide.move_to_next
    Action.update_status(self)
    @renderer.post_move_in_slide(old_index, slide.drawing_index)
  else
    move_to_next_slide_if_can
  end
end
move_to_next_slide_if_can() click to toggle source
# File lib/rabbit/canvas.rb, line 480
def move_to_next_slide_if_can
  move_to_if_can(current_index + 1)
end
move_to_previous_if_can() click to toggle source
# File lib/rabbit/canvas.rb, line 484
def move_to_previous_if_can
  slide = current_slide
  if slide and !slide.first?
    old_index = slide.drawing_index
    slide.move_to_previous
    Action.update_status(self)
    @renderer.post_move_in_slide(old_index, slide.drawing_index)
  else
    move_to_previous_slide_if_can
  end
end
move_to_previous_slide_if_can() click to toggle source
# File lib/rabbit/canvas.rb, line 496
def move_to_previous_slide_if_can
  move_to_if_can(current_index - 1)
end
need_reload_source?() click to toggle source
# File lib/rabbit/canvas.rb, line 393
def need_reload_source?
  !@processing and @source and @source.modified?
end
next_slide() click to toggle source
# File lib/rabbit/canvas.rb, line 317
def next_slide
  slides[current_index + 1]
end
on_comment(name, &callback) click to toggle source
# File lib/rabbit/canvas.rb, line 604
def on_comment(name, &callback)
  @on_comment_callbacks << [name, callback]
end
parse(source=nil, progress=nil) { |$!| ... } click to toggle source
# File lib/rabbit/canvas.rb, line 350
def parse(source=nil, progress=nil, &block)
  id = Object.new.__id__
  @parse_request_queue.push(id)
  @source = source || @source
  begin
    index = current_index
    current_allotted_time = allotted_time
    keep_index do
      @renderer.pre_parse
      clear
      Parser.parse(self, @source, progress: progress)
      new_allotted_time = allotted_time
      reset_timer if new_allotted_time != current_allotted_time
      apply_timer
      set_current_index(index)
      reload_theme do
        if @parse_request_queue.last != id
          raise ParseFinish
        end
        progress.call if progress
      end
      @renderer.post_parse
      index = current_index
    end
    set_current_index(index)
  rescue ParseFinish
  rescue ParseError, UnsupportedFormatError
    if block_given?
      yield($!)
    else
      logger.warn($!.message)
    end
  ensure
    @parse_request_queue.delete_if {|x| x == id}
  end
end
parsing?() click to toggle source
# File lib/rabbit/canvas.rb, line 190
def parsing?
  not @parse_request_queue.empty?
end
post_terminal() click to toggle source
# File lib/rabbit/canvas.rb, line 447
def post_terminal
  @renderer.post_terminal
end
pre_terminal() click to toggle source
# File lib/rabbit/canvas.rb, line 443
def pre_terminal
  @renderer.pre_terminal
end
print(&block) click to toggle source
processing?() click to toggle source
# File lib/rabbit/canvas.rb, line 579
def processing?
  @processing
end
quit() click to toggle source
# File lib/rabbit/canvas.rb, line 202
def quit
  @quitted = true
  @frame.quit
end
quitted?() click to toggle source
# File lib/rabbit/canvas.rb, line 186
def quitted?
  @quitted
end
reload_source(progress=nil, &block) click to toggle source
# File lib/rabbit/canvas.rb, line 387
def reload_source(progress=nil, &block)
  if need_reload_source?
    parse(nil, progress, &block)
  end
end
reload_theme(&block) click to toggle source
# File lib/rabbit/canvas.rb, line 346
def reload_theme(&block)
  apply_theme(@theme_name, &block)
end
reset_timer() click to toggle source
# File lib/rabbit/canvas.rb, line 685
def reset_timer
  @limit_time = nil
end
rest_time() click to toggle source
# File lib/rabbit/canvas.rb, line 681
def rest_time
  @limit_time ? @limit_time - Time.now : nil
end
save_as_image() click to toggle source
# File lib/rabbit/canvas.rb, line 411
def save_as_image
  process do
    generator = HTML::Generator.new(self,
                                    saved_image_base_name,
                                    @saved_image_type,
                                    @output_html,
                                    @output_index_html,
                                    @rss_base_uri)
    generator.pdf_filename = filename if /\.pdf\z/i =~ filename.to_s
    generator.source_filename = @source_filename
    generator.save
  end
end
saved_image_base_name() click to toggle source
# File lib/rabbit/canvas.rb, line 451
def saved_image_base_name
  if @saved_image_base_name
    base_name = @saved_image_base_name.encode("UTF-8")
  else
    base_name = Filename.sanitize(title)
  end
  base_name << "-index" if index_mode?
  base_name
end
slide_index(pattern) click to toggle source
# File lib/rabbit/canvas.rb, line 260
def slide_index(pattern)
  slides.each_with_index do |slide, i|
    return i if slide.match?(pattern)
  end
  nil
end
slide_indexes(pattern) click to toggle source
# File lib/rabbit/canvas.rb, line 267
def slide_indexes(pattern)
  indexes = []
  slides.each_with_index do |slide, i|
    indexes << i if slide.match?(pattern)
  end
  indexes
end
slide_size() click to toggle source
# File lib/rabbit/canvas.rb, line 275
def slide_size
  slides.size
end
slide_text(index=current_index) click to toggle source
# File lib/rabbit/canvas.rb, line 241
def slide_text(index=current_index)
  return "" if slides.empty?
  slide = slides[index]
  return "" if slide.nil?
  slide.text.strip
end
slide_title(index=current_index) click to toggle source
# File lib/rabbit/canvas.rb, line 230
def slide_title(index=current_index)
  return "" if slides.empty?
  slide = slides[index]
  return title if slide.nil?
  if slide.is_a?(Element::TitleSlide)
    slide.title
  else
    "#{title}: #{slide.title}"
  end
end
slides() click to toggle source
# File lib/rabbit/canvas.rb, line 248
def slides
  if @index_mode
    @index_slides
  else
    @slides
  end
end
source() click to toggle source
# File lib/rabbit/canvas.rb, line 541
def source
  @source.read
end
source_force_modified(force_modified) { |source| ... } click to toggle source
# File lib/rabbit/canvas.rb, line 534
def source_force_modified(force_modified)
  prev = @source.force_modified
  @source.force_modified = force_modified
  yield @source
  @source.force_modified = prev
end
start_auto_redraw_timer(interval) click to toggle source
# File lib/rabbit/canvas.rb, line 583
def start_auto_redraw_timer(interval)
  stop_auto_redraw_timer
  timer = GLib::Timeout.add(interval * 1000) do
    if quitted?
      @auto_redraw_timer = nil
      GLib::Source::REMOVE
    else
      activate("Redraw")
      GLib::Source::CONTINUE
    end
  end
  @auto_redraw_timer = timer
end
start_timer(limit) click to toggle source
# File lib/rabbit/canvas.rb, line 677
def start_timer(limit)
  @limit_time = Time.now + limit
end
stop_auto_redraw_timer() click to toggle source
# File lib/rabbit/canvas.rb, line 597
def stop_auto_redraw_timer
  if @auto_redraw_timer
    GLib::Source.remove(@auto_redraw_timer)
    @auto_redraw_timer = nil
  end
end
theme_name() click to toggle source
# File lib/rabbit/canvas.rb, line 334
def theme_name
  @theme_name || default_theme || "default"
end
title() click to toggle source
# File lib/rabbit/canvas.rb, line 221
def title
  ts = title_slide
  if ts
    ts.title
  else
    "Rabbit"
  end
end
title_slide() click to toggle source
# File lib/rabbit/canvas.rb, line 627
def title_slide
  @slides.find{|x| x.is_a?(Element::TitleSlide)}
end
tmp_dir_name() click to toggle source
# File lib/rabbit/canvas.rb, line 401
def tmp_dir_name
  @source and @source.tmp_dir_name
end
to_pixbuf(i) click to toggle source
# File lib/rabbit/canvas.rb, line 405
def to_pixbuf(i)
  move_to_if_can(i)
  current_slide.flush
  @renderer.to_pixbuf(current_slide)
end
toggle_index_mode() click to toggle source
# File lib/rabbit/canvas.rb, line 512
def toggle_index_mode
  @renderer.pre_toggle_index_mode
  process do
    if @index_mode
      @index_mode = false
      @renderer.index_mode_off
    else
      update_index_slides
      @index_mode = true
      @renderer.index_mode_on
    end
    modified
  end
  @renderer.post_toggle_index_mode
end
unfullscreened() click to toggle source
# File lib/rabbit/canvas.rb, line 435
def unfullscreened
  @renderer.post_unfullscreen
end
update_index_slides() click to toggle source
# File lib/rabbit/canvas.rb, line 528
def update_index_slides
  if @index_slides.empty?
    @index_slides = Element::IndexSlide.make_index_slides(self)
  end
end
use_gl?() click to toggle source
# File lib/rabbit/canvas.rb, line 198
def use_gl?
  @use_gl
end
with_index_mode(new_value) { || ... } click to toggle source
# File lib/rabbit/canvas.rb, line 651
def with_index_mode(new_value)
  current_index_mode = @index_mode
  @index_mode = new_value
  update_index_slides if @index_mode
  yield
ensure
  @index_mode = current_index_mode
end

Private Instance Methods

_apply_theme(name, id, &block) click to toggle source
# File lib/rabbit/canvas.rb, line 710
def _apply_theme(name, id, &block)
  @theme_name = name if name
  _theme_name = name || theme_name
  if _theme_name and not @slides.empty?
    @apply_theme_request_queue.push(id)
    success = false
    index_mode = @index_mode
    begin
      Action.update_status(self)
      clear_theme
      clear_index_slides
      manager = Theme::Manager.new(self) do
        if @apply_theme_request_queue.last != id
          raise ApplyFinish
        end
        block.call if block
      end
      manager.apply(_theme_name)
      @renderer.post_apply_theme
      success = true
    rescue ApplyFinish
    ensure
      @apply_theme_request_queue.delete_if {|x| x == id}
      Action.update_status(self)
    end
    activate("ToggleIndexMode") if success and index_mode
  end
end
clear() click to toggle source
# File lib/rabbit/canvas.rb, line 758
def clear
  clear_comments
  stop_auto_redraw_timer
  clear_slides
  clear_index_slides
  modified
end
clear_comments() click to toggle source
# File lib/rabbit/canvas.rb, line 766
def clear_comments
  @comments = []
  @on_comment_callbacks = []
end
clear_index_slides() click to toggle source
# File lib/rabbit/canvas.rb, line 776
def clear_index_slides
  activate("ToggleIndexMode") if @index_mode
  @index_current_index = 0
  @index_slides = []
end
clear_slides() click to toggle source
# File lib/rabbit/canvas.rb, line 771
def clear_slides
  @current_index = 0
  @slides = []
end
clear_theme() click to toggle source
# File lib/rabbit/canvas.rb, line 782
def clear_theme
  @font_resolution_ratio = 1
  @slides.each do |slide|
    slide.clear_theme
  end
  @renderer.clear_theme
  modified
end
default_theme() click to toggle source
# File lib/rabbit/canvas.rb, line 801
def default_theme
  ts = title_slide
  ts and ts.theme
end
keep_index() { || ... } click to toggle source
# File lib/rabbit/canvas.rb, line 791
def keep_index
  index_mode = @index_mode
  index = @current_index
  index_index = @index_current_index
  yield
  @current_index = index
  @index_current_index = index_index
  @index_mode = index_mode
end
modified() click to toggle source
# File lib/rabbit/canvas.rb, line 754
def modified
  @last_modified = Time.now
end
move_to(index) click to toggle source
# File lib/rabbit/canvas.rb, line 814
def move_to(index)
  old_index = current_index
  set_current_index(index)
  Action.update_status(self)
  @renderer.post_move(old_index, current_index)
end
process() { || ... } click to toggle source
# File lib/rabbit/canvas.rb, line 739
def process
  if @processing
    @logger.info(_("Processing..."))
    return
  end
  begin
    @processing = true
    Action.update_status(self)
    yield
  ensure
    @processing = false
    Action.update_status(self)
  end
end
set_current_index(new_index) click to toggle source
# File lib/rabbit/canvas.rb, line 806
def set_current_index(new_index)
  if @index_mode
    @index_current_index = new_index
  else
    @current_index = new_index
  end
end