thinreports 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +3 -3
  3. data/.github/workflows/test.yml +28 -36
  4. data/.gitignore +1 -1
  5. data/CHANGELOG.md +19 -1
  6. data/Gemfile +11 -0
  7. data/README.md +12 -17
  8. data/Rakefile +17 -11
  9. data/lib/thinreports/basic_report/core/errors.rb +62 -0
  10. data/lib/thinreports/basic_report/core/format/base.rb +91 -0
  11. data/lib/thinreports/basic_report/core/shape/base/interface.rb +42 -0
  12. data/lib/thinreports/basic_report/core/shape/base/internal.rb +53 -0
  13. data/lib/thinreports/basic_report/core/shape/basic/block_format.rb +15 -0
  14. data/lib/thinreports/basic_report/core/shape/basic/block_interface.rb +34 -0
  15. data/lib/thinreports/basic_report/core/shape/basic/block_internal.rb +36 -0
  16. data/lib/thinreports/basic_report/core/shape/basic/format.rb +24 -0
  17. data/lib/thinreports/basic_report/core/shape/basic/interface.rb +87 -0
  18. data/lib/thinreports/basic_report/core/shape/basic/internal.rb +28 -0
  19. data/lib/thinreports/{core → basic_report/core}/shape/basic.rb +6 -4
  20. data/lib/thinreports/basic_report/core/shape/image_block/format.rb +14 -0
  21. data/lib/thinreports/basic_report/core/shape/image_block/interface.rb +25 -0
  22. data/lib/thinreports/basic_report/core/shape/image_block/internal.rb +19 -0
  23. data/lib/thinreports/{core → basic_report/core}/shape/image_block.rb +6 -4
  24. data/lib/thinreports/basic_report/core/shape/list/format.rb +92 -0
  25. data/lib/thinreports/basic_report/core/shape/list/manager.rb +231 -0
  26. data/lib/thinreports/basic_report/core/shape/list/page.rb +112 -0
  27. data/lib/thinreports/basic_report/core/shape/list/page_state.rb +50 -0
  28. data/lib/thinreports/basic_report/core/shape/list/section_format.rb +37 -0
  29. data/lib/thinreports/basic_report/core/shape/list/section_interface.rb +51 -0
  30. data/lib/thinreports/basic_report/core/shape/list/section_internal.rb +33 -0
  31. data/lib/thinreports/{core → basic_report/core}/shape/list.rb +6 -4
  32. data/lib/thinreports/basic_report/core/shape/manager/format.rb +33 -0
  33. data/lib/thinreports/basic_report/core/shape/manager/internal.rb +109 -0
  34. data/lib/thinreports/basic_report/core/shape/manager/target.rb +114 -0
  35. data/lib/thinreports/basic_report/core/shape/page_number/format.rb +32 -0
  36. data/lib/thinreports/basic_report/core/shape/page_number/interface.rb +31 -0
  37. data/lib/thinreports/basic_report/core/shape/page_number/internal.rb +57 -0
  38. data/lib/thinreports/{core → basic_report/core}/shape/page_number.rb +6 -4
  39. data/lib/thinreports/basic_report/core/shape/stack_view/format.rb +29 -0
  40. data/lib/thinreports/basic_report/core/shape/stack_view/interface.rb +19 -0
  41. data/lib/thinreports/basic_report/core/shape/stack_view/internal.rb +24 -0
  42. data/lib/thinreports/basic_report/core/shape/stack_view/row_format.rb +41 -0
  43. data/lib/thinreports/{core → basic_report/core}/shape/stack_view.rb +6 -4
  44. data/lib/thinreports/basic_report/core/shape/style/base.rb +149 -0
  45. data/lib/thinreports/basic_report/core/shape/style/basic.rb +24 -0
  46. data/lib/thinreports/basic_report/core/shape/style/graphic.rb +43 -0
  47. data/lib/thinreports/basic_report/core/shape/style/text.rb +122 -0
  48. data/lib/thinreports/basic_report/core/shape/text/format.rb +17 -0
  49. data/lib/thinreports/basic_report/core/shape/text/interface.rb +20 -0
  50. data/lib/thinreports/basic_report/core/shape/text/internal.rb +24 -0
  51. data/lib/thinreports/{core → basic_report/core}/shape/text.rb +6 -4
  52. data/lib/thinreports/basic_report/core/shape/text_block/format.rb +43 -0
  53. data/lib/thinreports/basic_report/core/shape/text_block/formatter/basic.rb +41 -0
  54. data/lib/thinreports/basic_report/core/shape/text_block/formatter/datetime.rb +25 -0
  55. data/lib/thinreports/basic_report/core/shape/text_block/formatter/number.rb +69 -0
  56. data/lib/thinreports/basic_report/core/shape/text_block/formatter/padding.rb +27 -0
  57. data/lib/thinreports/basic_report/core/shape/text_block/formatter.rb +38 -0
  58. data/lib/thinreports/basic_report/core/shape/text_block/interface.rb +37 -0
  59. data/lib/thinreports/basic_report/core/shape/text_block/internal.rb +75 -0
  60. data/lib/thinreports/{core → basic_report/core}/shape/text_block.rb +6 -4
  61. data/lib/thinreports/basic_report/core/shape.rb +44 -0
  62. data/lib/thinreports/basic_report/core/utils.rb +47 -0
  63. data/lib/thinreports/basic_report/generator/pdf/document/draw_shape.rb +108 -0
  64. data/lib/thinreports/basic_report/generator/pdf/document/draw_template_items.rb +71 -0
  65. data/lib/thinreports/basic_report/generator/pdf/document/font.rb +90 -0
  66. data/lib/thinreports/basic_report/generator/pdf/document/graphics/attributes.rb +149 -0
  67. data/lib/thinreports/basic_report/generator/pdf/document/graphics/basic.rb +137 -0
  68. data/lib/thinreports/basic_report/generator/pdf/document/graphics/image.rb +99 -0
  69. data/lib/thinreports/basic_report/generator/pdf/document/graphics/text.rb +180 -0
  70. data/lib/thinreports/basic_report/generator/pdf/document/graphics.rb +42 -0
  71. data/lib/thinreports/basic_report/generator/pdf/document/page.rb +96 -0
  72. data/lib/thinreports/basic_report/generator/pdf/document/parse_color.rb +51 -0
  73. data/lib/thinreports/basic_report/generator/pdf/document.rb +132 -0
  74. data/lib/thinreports/basic_report/generator/pdf/drawer/base.rb +50 -0
  75. data/lib/thinreports/basic_report/generator/pdf/drawer/list.rb +65 -0
  76. data/lib/thinreports/basic_report/generator/pdf/drawer/list_section.rb +51 -0
  77. data/lib/thinreports/basic_report/generator/pdf/drawer/page.rb +127 -0
  78. data/lib/thinreports/basic_report/generator/pdf/prawn_ext/calc_image_dimensions.rb +34 -0
  79. data/lib/thinreports/basic_report/generator/pdf/prawn_ext/width_of.rb +31 -0
  80. data/lib/thinreports/basic_report/generator/pdf.rb +66 -0
  81. data/lib/thinreports/basic_report/layout/base.rb +48 -0
  82. data/lib/thinreports/basic_report/layout/format.rb +67 -0
  83. data/lib/thinreports/basic_report/layout/legacy_schema.rb +383 -0
  84. data/lib/thinreports/basic_report/layout/version.rb +41 -0
  85. data/lib/thinreports/{layout.rb → basic_report/layout.rb} +6 -4
  86. data/lib/thinreports/basic_report/report/base.rb +173 -0
  87. data/lib/thinreports/basic_report/report/internal.rb +107 -0
  88. data/lib/thinreports/basic_report/report/page.rb +97 -0
  89. data/lib/thinreports/basic_report/report.rb +26 -0
  90. data/lib/thinreports/basic_report.rb +15 -0
  91. data/lib/thinreports/config.rb +1 -1
  92. data/lib/thinreports/section_report.rb +12 -0
  93. data/lib/thinreports/version.rb +1 -1
  94. data/lib/thinreports.rb +2 -13
  95. data/thinreports.gemspec +3 -7
  96. metadata +97 -154
  97. data/gemfiles/prawn-2.2.gemfile +0 -5
  98. data/gemfiles/prawn-2.3.gemfile +0 -5
  99. data/gemfiles/prawn-2.4.gemfile +0 -5
  100. data/lib/thinreports/core/errors.rb +0 -60
  101. data/lib/thinreports/core/format/base.rb +0 -89
  102. data/lib/thinreports/core/shape/base/interface.rb +0 -40
  103. data/lib/thinreports/core/shape/base/internal.rb +0 -51
  104. data/lib/thinreports/core/shape/basic/block_format.rb +0 -13
  105. data/lib/thinreports/core/shape/basic/block_interface.rb +0 -32
  106. data/lib/thinreports/core/shape/basic/block_internal.rb +0 -34
  107. data/lib/thinreports/core/shape/basic/format.rb +0 -22
  108. data/lib/thinreports/core/shape/basic/interface.rb +0 -85
  109. data/lib/thinreports/core/shape/basic/internal.rb +0 -26
  110. data/lib/thinreports/core/shape/image_block/format.rb +0 -12
  111. data/lib/thinreports/core/shape/image_block/interface.rb +0 -23
  112. data/lib/thinreports/core/shape/image_block/internal.rb +0 -17
  113. data/lib/thinreports/core/shape/list/format.rb +0 -90
  114. data/lib/thinreports/core/shape/list/manager.rb +0 -229
  115. data/lib/thinreports/core/shape/list/page.rb +0 -110
  116. data/lib/thinreports/core/shape/list/page_state.rb +0 -48
  117. data/lib/thinreports/core/shape/list/section_format.rb +0 -35
  118. data/lib/thinreports/core/shape/list/section_interface.rb +0 -49
  119. data/lib/thinreports/core/shape/list/section_internal.rb +0 -31
  120. data/lib/thinreports/core/shape/manager/format.rb +0 -31
  121. data/lib/thinreports/core/shape/manager/internal.rb +0 -107
  122. data/lib/thinreports/core/shape/manager/target.rb +0 -112
  123. data/lib/thinreports/core/shape/page_number/format.rb +0 -30
  124. data/lib/thinreports/core/shape/page_number/interface.rb +0 -29
  125. data/lib/thinreports/core/shape/page_number/internal.rb +0 -55
  126. data/lib/thinreports/core/shape/stack_view/format.rb +0 -27
  127. data/lib/thinreports/core/shape/stack_view/interface.rb +0 -17
  128. data/lib/thinreports/core/shape/stack_view/internal.rb +0 -22
  129. data/lib/thinreports/core/shape/stack_view/row_format.rb +0 -39
  130. data/lib/thinreports/core/shape/style/base.rb +0 -146
  131. data/lib/thinreports/core/shape/style/basic.rb +0 -22
  132. data/lib/thinreports/core/shape/style/graphic.rb +0 -41
  133. data/lib/thinreports/core/shape/style/text.rb +0 -120
  134. data/lib/thinreports/core/shape/text/format.rb +0 -15
  135. data/lib/thinreports/core/shape/text/interface.rb +0 -18
  136. data/lib/thinreports/core/shape/text/internal.rb +0 -22
  137. data/lib/thinreports/core/shape/text_block/format.rb +0 -41
  138. data/lib/thinreports/core/shape/text_block/formatter/basic.rb +0 -39
  139. data/lib/thinreports/core/shape/text_block/formatter/datetime.rb +0 -23
  140. data/lib/thinreports/core/shape/text_block/formatter/number.rb +0 -67
  141. data/lib/thinreports/core/shape/text_block/formatter/padding.rb +0 -25
  142. data/lib/thinreports/core/shape/text_block/formatter.rb +0 -34
  143. data/lib/thinreports/core/shape/text_block/interface.rb +0 -35
  144. data/lib/thinreports/core/shape/text_block/internal.rb +0 -73
  145. data/lib/thinreports/core/shape.rb +0 -42
  146. data/lib/thinreports/core/utils.rb +0 -45
  147. data/lib/thinreports/generate.rb +0 -11
  148. data/lib/thinreports/generator/pdf/document/draw_shape.rb +0 -106
  149. data/lib/thinreports/generator/pdf/document/draw_template_items.rb +0 -69
  150. data/lib/thinreports/generator/pdf/document/font.rb +0 -88
  151. data/lib/thinreports/generator/pdf/document/graphics/attributes.rb +0 -147
  152. data/lib/thinreports/generator/pdf/document/graphics/basic.rb +0 -135
  153. data/lib/thinreports/generator/pdf/document/graphics/image.rb +0 -98
  154. data/lib/thinreports/generator/pdf/document/graphics/text.rb +0 -178
  155. data/lib/thinreports/generator/pdf/document/graphics.rb +0 -40
  156. data/lib/thinreports/generator/pdf/document/page.rb +0 -94
  157. data/lib/thinreports/generator/pdf/document/parse_color.rb +0 -49
  158. data/lib/thinreports/generator/pdf/document.rb +0 -130
  159. data/lib/thinreports/generator/pdf/drawer/base.rb +0 -48
  160. data/lib/thinreports/generator/pdf/drawer/list.rb +0 -63
  161. data/lib/thinreports/generator/pdf/drawer/list_section.rb +0 -49
  162. data/lib/thinreports/generator/pdf/drawer/page.rb +0 -125
  163. data/lib/thinreports/generator/pdf/prawn_ext/calc_image_dimensions.rb +0 -32
  164. data/lib/thinreports/generator/pdf/prawn_ext/width_of.rb +0 -29
  165. data/lib/thinreports/generator/pdf.rb +0 -63
  166. data/lib/thinreports/layout/base.rb +0 -46
  167. data/lib/thinreports/layout/format.rb +0 -65
  168. data/lib/thinreports/layout/legacy_schema.rb +0 -381
  169. data/lib/thinreports/layout/version.rb +0 -39
  170. data/lib/thinreports/report/base.rb +0 -169
  171. data/lib/thinreports/report/internal.rb +0 -105
  172. data/lib/thinreports/report/page.rb +0 -95
  173. data/lib/thinreports/report.rb +0 -24
  174. /data/lib/thinreports/{core → basic_report/core}/shape/base.rb +0 -0
  175. /data/lib/thinreports/{core → basic_report/core}/shape/manager.rb +0 -0
  176. /data/lib/thinreports/{core → basic_report/core}/shape/style.rb +0 -0
  177. /data/lib/thinreports/{generator → basic_report/generator}/pdf/prawn_ext.rb +0 -0
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module Basic
8
+ class Interface < Base::Interface
9
+ internal_delegators :type
10
+
11
+ # @return [String]
12
+ def id
13
+ internal.id.dup
14
+ end
15
+
16
+ # @param [Boolean] visibility
17
+ # @return [self]
18
+ def visible(visibility)
19
+ internal.style.visible = visibility
20
+ self
21
+ end
22
+
23
+ # @return [Boolean]
24
+ def visible?
25
+ internal.style.visible
26
+ end
27
+
28
+ # @overload style(style_name)
29
+ # @param [Symbol] style_name
30
+ # @return [Object]
31
+ # @overload style(style_name, value)
32
+ # @param [Symbol] style_name
33
+ # @param [String, Symbol, Number, Array] value
34
+ # @return [self]
35
+ # @overload style(style_name, value1, value2)
36
+ # @param [Symbol] style_name
37
+ # @param [String, Number] value1
38
+ # @param [String, Number] value2
39
+ # @return [self]
40
+ def style(*args)
41
+ case args.length
42
+ when 1
43
+ internal.style[args.first]
44
+ when 2
45
+ internal.style[args.first] = args.last
46
+ self
47
+ when 3
48
+ internal.style[args.shift] = args
49
+ self
50
+ else
51
+ raise ArgumentError, '#style requires 1 or 2, 3 arguments'
52
+ end
53
+ end
54
+
55
+ # @param [Hash] settings style_name: value
56
+ # @return [self]
57
+ def styles(settings)
58
+ settings.each { |args| style(*args) }
59
+ self
60
+ end
61
+
62
+ # @see #visible
63
+ # @return [self]
64
+ def hide
65
+ visible(false)
66
+ self
67
+ end
68
+
69
+ # @see #visible
70
+ # @return [self]
71
+ def show
72
+ visible(true)
73
+ self
74
+ end
75
+
76
+ private
77
+
78
+ # @see Thinreports::BasicReport::Core::Shape::Base::Interface#init_internal
79
+ def init_internal(parent, format)
80
+ Basic::Internal.new(parent, format)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module Basic
8
+ class Internal < Base::Internal
9
+ # Delegate to Format's methods
10
+ format_delegators :id, :type
11
+
12
+ def style
13
+ @style ||= Style::Graphic.new(format)
14
+ end
15
+
16
+ def type_of?(type_name)
17
+ [:basic, type].include?(type_name)
18
+ end
19
+
20
+ def identifier
21
+ "#{id}#{style.identifier}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Thinreports
4
- module Core
5
- module Shape
6
- module Basic
7
- TYPE_NAMES = %w[line rect ellipse image].freeze
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module Basic
8
+ TYPE_NAMES = %w[line rect ellipse image].freeze
9
+ end
8
10
  end
9
11
  end
10
12
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module ImageBlock
8
+ class Format < Basic::BlockFormat
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module ImageBlock
8
+ class Interface < Basic::BlockInterface
9
+ # @see #value
10
+ alias src value
11
+ # @see #value=
12
+ alias src= value=
13
+
14
+ private
15
+
16
+ # @see Thinreports::BasicReport::Core::Shape::Base::Interface#init_internal
17
+ def init_internal(parent, format)
18
+ ImageBlock::Internal.new(parent, format)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module ImageBlock
8
+ class Internal < Basic::BlockInternal
9
+ alias src read_value
10
+
11
+ def type_of?(type_name)
12
+ type_name == ImageBlock::TYPE_NAME || super
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Thinreports
4
- module Core
5
- module Shape
6
- module ImageBlock
7
- TYPE_NAME = 'image-block'
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module ImageBlock
8
+ TYPE_NAME = 'image-block'
9
+ end
8
10
  end
9
11
  end
10
12
  end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module List
8
+ class Format < Basic::Format
9
+ config_reader height: %w[content-height]
10
+ config_checker true, auto_page_break: %w[auto-page-break]
11
+
12
+ # @deprecated
13
+ config_reader :header,
14
+ :detail,
15
+ :footer
16
+ # @deprecated
17
+ config_reader page_footer: %w[page-footer]
18
+
19
+ config_checker true, has_header: %w[header enabled]
20
+ config_checker true, has_footer: %w[footer enabled]
21
+ config_checker true, has_page_footer: %w[page-footer enabled]
22
+
23
+ config_reader page_footer_height: %w[page-footer height]
24
+ config_reader footer_height: %w[footer height]
25
+ config_reader header_height: %w[header height]
26
+ config_reader detail_height: %w[detail height]
27
+
28
+ attr_reader :sections
29
+
30
+ def initialize(*)
31
+ super
32
+ initialize_sections
33
+ end
34
+
35
+ # @param [Symbol] section_name
36
+ # @return [Hash]
37
+ # @deprecated
38
+ def section(section_name)
39
+ __send__(section_name)
40
+ end
41
+
42
+ # @param [Symbol] section_name
43
+ # @return [Boolean]
44
+ def has_section?(section_name)
45
+ section_name == :detail ? true : __send__(:"has_#{section_name}?")
46
+ end
47
+
48
+ # @param [Symbol] section_name
49
+ # @return [Numeric]
50
+ def section_height(section_name)
51
+ has_section?(section_name) ? __send__(:"#{section_name}_height") : 0
52
+ end
53
+
54
+ # @param [:detai, :header, :page_footer, :footer] section_name
55
+ # @return [Numeric]
56
+ def section_base_position_top(section_name)
57
+ section = @sections[section_name]
58
+ return 0 unless has_section?(section_name)
59
+
60
+ top = section.relative_top
61
+
62
+ case section_name
63
+ when :page_footer
64
+ top - section_height(:detail)
65
+ when :footer
66
+ top - section_height(:detail) - section_height(:page_footer)
67
+ else
68
+ top
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def initialize_sections
75
+ @sections = {
76
+ detail: List::SectionFormat.new(attributes['detail'])
77
+ }
78
+
79
+ @sections[:header] = section_format('header') if has_section?(:header)
80
+ @sections[:page_footer] = section_format('page-footer') if has_section?(:page_footer)
81
+ @sections[:footer] = section_format('footer') if has_section?(:footer)
82
+ end
83
+
84
+ def section_format(section_name)
85
+ List::SectionFormat.new(attributes[section_name])
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,231 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module List
8
+ class Manager
9
+ include Utils
10
+
11
+ # @return [Thinreports::BasicReport::Core::Shape:::List::Page]
12
+ attr_reader :current_page
13
+
14
+ # @return [Thinreports::BasicReport::Core::Shape::List::PageState]
15
+ attr_reader :current_page_state
16
+
17
+ # @return [Integer]
18
+ attr_accessor :page_count
19
+
20
+ # @return [Proc]
21
+ attr_accessor :page_finalize_handler
22
+
23
+ # @return [Proc]
24
+ attr_accessor :page_footer_handler
25
+
26
+ # @return [Proc]
27
+ attr_accessor :footer_handler
28
+
29
+ # @param [Thinreports::BasicReport::Core::Shape::List::Page] page
30
+ def initialize(page)
31
+ switch_current!(page)
32
+
33
+ @finalized = false
34
+ @page_count = 0
35
+
36
+ @page_finalize_handler = nil
37
+ @page_footer_handler = nil
38
+ @footer_handler = nil
39
+ end
40
+
41
+ # @param [Thinreports::BasicReport::Core::Shape::List::Page] page
42
+ # @return [Thinreports::BasicReport::Core::Shape::List::Manager]
43
+ def switch_current!(page)
44
+ @current_page = page
45
+ @current_page_state = page.internal
46
+ self
47
+ end
48
+
49
+ # @yield [new_list]
50
+ # @yieldparam [Thinreports::BasicReport::Core::Shape::List::Page] new_list
51
+ def change_new_page(&block)
52
+ finalize_page
53
+ new_page = report.internal.copy_page
54
+
55
+ block.call(new_page.list(current_page.id)) if block_given?
56
+ end
57
+
58
+ # @param [Hash] values ({})
59
+ # @yield [header]
60
+ # @yieldparam [Thinreports::BasicReport::Core::Shape::List::SectionInterface] header
61
+ # @return [Thinreports::BasicReport::Core::Shape::List::SectionInterface]
62
+ # @raise [Thinreports::BasicReport::Errors::DisabledListSection]
63
+ def build_header(values = {}, &block)
64
+ raise Thinreports::BasicReport::Errors::DisabledListSection, 'header' unless format.has_header?
65
+
66
+ current_page_state.header ||= init_section(:header)
67
+ build_section(header_section, values, &block)
68
+ end
69
+
70
+ # @return [Thinreports::BasicReport::Core::Shape::List::SectionInterface]
71
+ def header_section
72
+ current_page_state.header
73
+ end
74
+
75
+ # @param (see #build_section)
76
+ # @return [Boolean]
77
+ def add_detail(values = {}, &block)
78
+ return false if current_page_state.finalized?
79
+
80
+ successful = true
81
+
82
+ if overflow_with?(:detail)
83
+ if auto_page_break?
84
+ change_new_page do |new_list|
85
+ new_list.manager.insert_detail(values, &block)
86
+ end
87
+ else
88
+ finalize
89
+ successful = false
90
+ end
91
+ else
92
+ insert_detail(values, &block)
93
+ end
94
+ successful
95
+ end
96
+
97
+ # @param values (see Thinreports::BasicReport::Core::Shape::Manager::Target#values)
98
+ # @yield [section,]
99
+ # @yieldparam [Thinreports::BasicReport::Core::Shape::List::SectionInterface] section
100
+ # @return [Thinreports::BasicReport::Core::Shape::List::SectionInterface]
101
+ def insert_detail(values = {}, &block)
102
+ detail = build_section(init_section(:detail), values, &block)
103
+ insert_row(detail)
104
+ end
105
+
106
+ # @param [Thinreports::BasicReport::Core::Shape::List::SectionInterface] row
107
+ # @return [Thinreports::BasicReport::Core::Shape::List::SectionInterface]
108
+ def insert_row(row)
109
+ row.internal.move_top_to(current_page_state.height)
110
+
111
+ current_page_state.rows << row
112
+ current_page_state.height += row.height
113
+ row
114
+ end
115
+
116
+ # @param [Thinreports::BasicReport::Core::Shape::List::SectionInterface] section
117
+ # @param values (see Thinreports::BasicReport::Core::Shape::Manager::Target#values)
118
+ # @yield [section,]
119
+ # @yieldparam [Thinreports::BasicReport::Core::Shape::List::SectionInterface] section
120
+ # @return [Thinreports::BasicReport::Core::Shape::List::SectionInterface]
121
+ def build_section(section, values = {}, &block)
122
+ section.values(values)
123
+ call_block_in(section, &block)
124
+ end
125
+
126
+ # @param [Symbol] section_name
127
+ # @return [Thinreports::BasicReport::Core::Shape::List::SectionInterface]
128
+ def init_section(section_name)
129
+ List::SectionInterface.new(current_page,
130
+ format.sections[section_name],
131
+ section_name)
132
+ end
133
+
134
+ # @param [Symbol] section_name
135
+ # @return [Boolean]
136
+ def overflow_with?(section_name = :detail)
137
+ max_height = page_max_height
138
+
139
+ max_height += format.section_height(:page_footer) if section_name == :footer && format.has_page_footer?
140
+
141
+ height = format.section_height(section_name)
142
+ (current_page_state.height + height) > max_height
143
+ end
144
+
145
+ # @return [Numeric]
146
+ def page_max_height
147
+ @page_max_height ||= begin
148
+ h = format.height
149
+ h -= format.section_height(:page_footer)
150
+ h -= format.section_height(:footer) unless auto_page_break?
151
+ h
152
+ end
153
+ end
154
+
155
+ # @return [Boolean]
156
+ def auto_page_break?
157
+ format.auto_page_break?
158
+ end
159
+
160
+ # @param [Hash] options
161
+ # @option options [Boolean] :ignore_page_footer (false)
162
+ # When the switch of the page is generated by #finalize, it is used.
163
+ def finalize_page(options = {})
164
+ return if current_page_state.finalized?
165
+
166
+ build_header if format.has_header?
167
+
168
+ finalize_page_footer unless options[:ignore_page_footer]
169
+
170
+ current_page_state.finalized!
171
+ @page_finalize_handler.call if @page_finalize_handler
172
+
173
+ @page_count += 1
174
+ current_page_state.no = @page_count
175
+ end
176
+
177
+ def finalize_page_footer
178
+ return unless format.has_page_footer?
179
+
180
+ page_footer = init_section(:page_footer)
181
+ insert_row(page_footer)
182
+
183
+ @page_footer_handler.call(page_footer) if @page_footer_handler
184
+ end
185
+
186
+ def finalize
187
+ return if finalized?
188
+ finalize_page
189
+
190
+ if format.has_footer?
191
+ footer = init_section(:footer)
192
+
193
+ @footer_handler.call(footer) if @footer_handler
194
+
195
+ if auto_page_break? && overflow_with?(:footer)
196
+ change_new_page do |new_list|
197
+ new_list.manager.insert_row(footer)
198
+ new_list.manager.finalize_page(ignore_page_footer: true)
199
+ end
200
+ else
201
+ insert_row(footer)
202
+ end
203
+ end
204
+ @finalized = true
205
+ end
206
+
207
+ # @return [Boolean]
208
+ def finalized?
209
+ @finalized
210
+ end
211
+
212
+ # @return [Thinreports::BasicReport::Report::Base]
213
+ def report
214
+ current_page_state.parent.report
215
+ end
216
+
217
+ # @return [Thinreports::BasicReport::Layout::Base]
218
+ def layout
219
+ current_page_state.parent.layout
220
+ end
221
+
222
+ # @return [Thinreports::BasicReport::Core::Shape::List::Format]
223
+ def format
224
+ current_page_state.format
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module List
8
+ class Page < Basic::Interface
9
+ extend Forwardable
10
+
11
+ attr_reader :manager
12
+
13
+ # @param [Thinreports::BasicReport::Report::Page] parent
14
+ # @param [Thinreports::BasicReport::Core::Shape::Basic::Format] format
15
+ # @param [Thinreports::BasicReport::Core::Shape::List::PageState] internal (nil)
16
+ # @param [Thinreports::BasicReport::Core::Shape::List::Manager] manager (nil)
17
+ def initialize(parent, format, internal = nil, manager = nil)
18
+ super(parent, format, internal)
19
+
20
+ @manager =
21
+ if manager
22
+ manager.switch_current!(self)
23
+ else
24
+ List::Manager.new(self)
25
+ end
26
+
27
+ # Set a reference to List::PageState List::Manager
28
+ self.internal.manager = self.manager
29
+ end
30
+
31
+ # @see Thinreports::BasicReport::Core::Shape::List::Manager#build_header
32
+ def_delegator :manager, :build_header, :header
33
+
34
+ def on_page_finalize(&block)
35
+ manager.page_finalize_handler = block
36
+ end
37
+
38
+ # @yield [page_footer]
39
+ # @yieldparam [Thinreports::BasicReport::Core::Shape::List::SectionInterface] page_footer
40
+ def on_page_footer_insert(&block)
41
+ manager.page_footer_handler = block
42
+ end
43
+
44
+ # @yield [footer]
45
+ # @yieldparam [Thinreports::BasicReport::Core::Shape::List::SectionInterface] footer
46
+ # @return [Thinreports::BasicReport::Core::Shape::List::SectionInterface]
47
+ def on_footer_insert(&block)
48
+ manager.footer_handler = block
49
+ end
50
+
51
+ # @param [Hash] values ({})
52
+ # @yield [row,]
53
+ # @yieldparam [Thinreports::BasicReport::Core::Shape::List::SectionInterface] row
54
+ # @return [Boolean]
55
+ def add_row(values = {}, &block)
56
+ manager.add_detail(values, &block)
57
+ end
58
+
59
+ # If enabled, the auto-page-break of the list will force a page break
60
+ # at the time this method is called. Otherwise, this list will be finalized.
61
+ def page_break
62
+ if manager.auto_page_break?
63
+ manager.change_new_page
64
+ else
65
+ manager.finalize_page
66
+ end
67
+ end
68
+ alias finalize page_break
69
+
70
+ # @return [Boolean] Returns true if list has overflowed
71
+ # when `list#add_row` is called at the next time.
72
+ def overflow?
73
+ manager.overflow_with?(:detail)
74
+ end
75
+
76
+ # @param [Thinreports::BasicReport::Report::Page] new_parent
77
+ # @return [Thinreports::BasicReport::Core::Shape::List::Page]
78
+ def copy(new_parent)
79
+ if manager.auto_page_break?
80
+ new_list = self.class.new(new_parent, internal.format,
81
+ nil, manager)
82
+ else
83
+ manager.finalize
84
+
85
+ new_list = self.class.new(new_parent, internal.format,
86
+ internal.copy(new_parent), manager)
87
+ internal.rows.each do |row|
88
+ new_list.internal.rows << row.copy(new_list)
89
+ end
90
+ new_list.internal.finalized!
91
+ end
92
+
93
+ new_list.internal.header = internal.header.copy(new_list) if internal.format.has_header?
94
+ new_list
95
+ end
96
+
97
+ private
98
+
99
+ # @see Thinreports::BasicReport::Core::Shape::Base::Interface#init_internal
100
+ def init_internal(parent, format)
101
+ List::PageState.new(parent, format)
102
+ end
103
+ end
104
+
105
+ # Alias to List::Page.
106
+ # @see Thinreports::BasicReport::Core::Shape::List::Page
107
+ List::Interface = List::Page
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module List
8
+ class PageState < Basic::Internal
9
+ attr_reader :rows
10
+
11
+ attr_accessor :height
12
+ attr_accessor :header
13
+ attr_accessor :no
14
+ attr_accessor :manager
15
+
16
+ def initialize(*args)
17
+ super(*args)
18
+
19
+ @rows = []
20
+ @height = 0
21
+ @finalized = false
22
+
23
+ @header = nil
24
+ end
25
+
26
+ def style
27
+ @style ||= Style::Basic.new(format)
28
+ end
29
+
30
+ def finalized?
31
+ @finalized
32
+ end
33
+
34
+ def finalized!
35
+ @finalized = true
36
+ end
37
+
38
+ def type_of?(type_name)
39
+ type_name == List::TYPE_NAME
40
+ end
41
+ end
42
+
43
+ # Alias to List::PageState.
44
+ # @see Thinreports::BasicReport::Core::Shape::List::PageState
45
+ List::Internal = List::PageState
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end