File: printing.rb

package info (click to toggle)
ruby-gnome2 3.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 28,872 kB
  • sloc: ansic: 96,386; ruby: 70,722; xml: 350; sh: 105; cpp: 45; makefile: 34
file content (128 lines) | stat: -rw-r--r-- 3,734 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# Copyright (c) 2008 Ruby-GNOME2 Project Team
# This program is licenced under the same licence as Ruby-GNOME2.
=begin
= Printing

Gtk::PrintOperation offers a simple API to support printing
in a cross-platform way.
=end

require 'common'

module Demo
  class Printing < BasicWindow
    Data = Struct.new(:font_size, :lines_per_page, :lines, :n_pages)
    HEADER_HEIGHT = 10 * 72 / 25.4
    HEADER_GAP = 3 * 72 / 25.4

    def initialize
      super('Printing')

      button = Gtk::Button.new("Print...")
      button.signal_connect("clicked") do
        begin
          run_print_operation
        rescue
          dialog = Gtk::MessageDialog.new(self, :destroy_with_parent, :error,
                                          :close, $!.message)
          dialog.signal_connect("response") do
            dialog.destroy
            true
          end
          dialog.show
        end
        true
      end
      add(button)
    end

    private
    def run_print_operation
      operation = Gtk::PrintOperation.new

      data = Data.new
      data.font_size = 12.0
      operation.signal_connect("begin-print") do |_operation, context|
        on_begin_print(_operation, context, data)
      end
      operation.signal_connect("draw-page") do |_operation, context, page_number|
        on_draw_page(_operation, context, page_number, data)
      end
      operation.signal_connect("end-print") do |_operation, context|
        on_end_print(_operation, context, data)
      end

      operation.use_full_page = false
      operation.unit = :points

      operation.run(:print_dialog, self)
    end

    def on_begin_print(operation, context, data)
      height = context.height - HEADER_HEIGHT - HEADER_GAP
      data.lines_per_page = (height / data.font_size).floor
      data.lines = File.readlines(__FILE__)
      data.n_pages = (data.lines.size - 1) / data.lines_per_page + 1
      operation.set_n_pages(data.n_pages)
    end

    def on_draw_page(operation, context, page_number, data)
      cr = context.cairo_context
      draw_header(cr, operation, context, page_number, data)
      draw_body(cr, operation, context, page_number, data)
    end

    def draw_header(cr, operation, context, page_number, data)
      width = context.width

      cr.rectangle(0, 0, width, HEADER_HEIGHT)
      cr.set_source_rgb(0.8, 0.8, 0.8)
      cr.fill_preserve

      cr.set_source_rgb(0, 0, 0)
      cr.line_width = 1
      cr.stroke

      layout = context.create_pango_layout
      layout.font_description = "sans 14"

      layout.text = File.basename(__FILE__)
      text_width, text_height = layout.pixel_size

      if (text_width > width)
        layout.width = width
        layout.ellipsize = :start
        text_width, text_height = layout.pixel_size
      end

      y = (HEADER_HEIGHT - text_height) / 2

      cr.move_to((width - text_width) / 2, y)
      cr.show_pango_layout(layout)

      layout.text = "#{page_number + 1}/#{data.n_pages}"
      layout.width = -1
      text_width, text_height = layout.pixel_size
      cr.move_to(width - text_width - 4, y)
      cr.show_pango_layout(layout)
    end

    def draw_body(cr, operation, context, page_number, data)
      layout = context.create_pango_layout
      description = Pango::FontDescription.new("monospace")
      description.size = data.font_size * Pango::SCALE
      layout.font_description = description

      cr.move_to(0, HEADER_HEIGHT + HEADER_GAP)
      start_line = page_number * data.lines_per_page
      data.lines[start_line, data.lines_per_page].each do |line|
        layout.text = line
        cr.show_pango_layout(layout)
        cr.rel_move_to(0, data.font_size)
      end
    end

    def on_end_print(operation, context, data)
    end
  end
end