thinreports 0.12.0 → 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 (181) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/test.yml +31 -40
  4. data/.gitignore +1 -1
  5. data/CHANGELOG.md +25 -1
  6. data/Gemfile +11 -0
  7. data/{MIT-LICENSE → LICENSE.txt} +2 -0
  8. data/README.md +50 -66
  9. data/Rakefile +17 -11
  10. data/lib/thinreports/basic_report/core/errors.rb +62 -0
  11. data/lib/thinreports/basic_report/core/format/base.rb +91 -0
  12. data/lib/thinreports/basic_report/core/shape/base/interface.rb +42 -0
  13. data/lib/thinreports/basic_report/core/shape/base/internal.rb +53 -0
  14. data/lib/thinreports/basic_report/core/shape/basic/block_format.rb +15 -0
  15. data/lib/thinreports/basic_report/core/shape/basic/block_interface.rb +34 -0
  16. data/lib/thinreports/basic_report/core/shape/basic/block_internal.rb +36 -0
  17. data/lib/thinreports/basic_report/core/shape/basic/format.rb +24 -0
  18. data/lib/thinreports/basic_report/core/shape/basic/interface.rb +87 -0
  19. data/lib/thinreports/basic_report/core/shape/basic/internal.rb +28 -0
  20. data/lib/thinreports/{core → basic_report/core}/shape/basic.rb +6 -4
  21. data/lib/thinreports/basic_report/core/shape/image_block/format.rb +14 -0
  22. data/lib/thinreports/basic_report/core/shape/image_block/interface.rb +25 -0
  23. data/lib/thinreports/basic_report/core/shape/image_block/internal.rb +19 -0
  24. data/lib/thinreports/{core → basic_report/core}/shape/image_block.rb +6 -4
  25. data/lib/thinreports/basic_report/core/shape/list/format.rb +92 -0
  26. data/lib/thinreports/basic_report/core/shape/list/manager.rb +231 -0
  27. data/lib/thinreports/basic_report/core/shape/list/page.rb +112 -0
  28. data/lib/thinreports/basic_report/core/shape/list/page_state.rb +50 -0
  29. data/lib/thinreports/basic_report/core/shape/list/section_format.rb +37 -0
  30. data/lib/thinreports/basic_report/core/shape/list/section_interface.rb +51 -0
  31. data/lib/thinreports/basic_report/core/shape/list/section_internal.rb +33 -0
  32. data/lib/thinreports/{core → basic_report/core}/shape/list.rb +6 -4
  33. data/lib/thinreports/basic_report/core/shape/manager/format.rb +33 -0
  34. data/lib/thinreports/basic_report/core/shape/manager/internal.rb +109 -0
  35. data/lib/thinreports/basic_report/core/shape/manager/target.rb +114 -0
  36. data/lib/thinreports/basic_report/core/shape/page_number/format.rb +32 -0
  37. data/lib/thinreports/basic_report/core/shape/page_number/interface.rb +31 -0
  38. data/lib/thinreports/basic_report/core/shape/page_number/internal.rb +57 -0
  39. data/lib/thinreports/{core → basic_report/core}/shape/page_number.rb +6 -4
  40. data/lib/thinreports/basic_report/core/shape/stack_view/format.rb +29 -0
  41. data/lib/thinreports/basic_report/core/shape/stack_view/interface.rb +19 -0
  42. data/lib/thinreports/basic_report/core/shape/stack_view/internal.rb +24 -0
  43. data/lib/thinreports/basic_report/core/shape/stack_view/row_format.rb +41 -0
  44. data/lib/thinreports/{core → basic_report/core}/shape/stack_view.rb +6 -4
  45. data/lib/thinreports/basic_report/core/shape/style/base.rb +149 -0
  46. data/lib/thinreports/basic_report/core/shape/style/basic.rb +24 -0
  47. data/lib/thinreports/basic_report/core/shape/style/graphic.rb +43 -0
  48. data/lib/thinreports/basic_report/core/shape/style/text.rb +122 -0
  49. data/lib/thinreports/basic_report/core/shape/text/format.rb +17 -0
  50. data/lib/thinreports/basic_report/core/shape/text/interface.rb +20 -0
  51. data/lib/thinreports/basic_report/core/shape/text/internal.rb +24 -0
  52. data/lib/thinreports/{core → basic_report/core}/shape/text.rb +6 -4
  53. data/lib/thinreports/basic_report/core/shape/text_block/format.rb +43 -0
  54. data/lib/thinreports/basic_report/core/shape/text_block/formatter/basic.rb +41 -0
  55. data/lib/thinreports/basic_report/core/shape/text_block/formatter/datetime.rb +25 -0
  56. data/lib/thinreports/basic_report/core/shape/text_block/formatter/number.rb +69 -0
  57. data/lib/thinreports/basic_report/core/shape/text_block/formatter/padding.rb +27 -0
  58. data/lib/thinreports/basic_report/core/shape/text_block/formatter.rb +38 -0
  59. data/lib/thinreports/basic_report/core/shape/text_block/interface.rb +37 -0
  60. data/lib/thinreports/basic_report/core/shape/text_block/internal.rb +75 -0
  61. data/lib/thinreports/{core → basic_report/core}/shape/text_block.rb +6 -4
  62. data/lib/thinreports/basic_report/core/shape.rb +44 -0
  63. data/lib/thinreports/basic_report/core/utils.rb +47 -0
  64. data/lib/thinreports/basic_report/generator/pdf/document/draw_shape.rb +108 -0
  65. data/lib/thinreports/basic_report/generator/pdf/document/draw_template_items.rb +71 -0
  66. data/lib/thinreports/basic_report/generator/pdf/document/font.rb +90 -0
  67. data/lib/thinreports/basic_report/generator/pdf/document/graphics/attributes.rb +149 -0
  68. data/lib/thinreports/basic_report/generator/pdf/document/graphics/basic.rb +137 -0
  69. data/lib/thinreports/basic_report/generator/pdf/document/graphics/image.rb +99 -0
  70. data/lib/thinreports/basic_report/generator/pdf/document/graphics/text.rb +180 -0
  71. data/lib/thinreports/basic_report/generator/pdf/document/graphics.rb +42 -0
  72. data/lib/thinreports/basic_report/generator/pdf/document/page.rb +96 -0
  73. data/lib/thinreports/basic_report/generator/pdf/document/parse_color.rb +51 -0
  74. data/lib/thinreports/basic_report/generator/pdf/document.rb +132 -0
  75. data/lib/thinreports/basic_report/generator/pdf/drawer/base.rb +50 -0
  76. data/lib/thinreports/basic_report/generator/pdf/drawer/list.rb +65 -0
  77. data/lib/thinreports/basic_report/generator/pdf/drawer/list_section.rb +51 -0
  78. data/lib/thinreports/basic_report/generator/pdf/drawer/page.rb +127 -0
  79. data/lib/thinreports/basic_report/generator/pdf/prawn_ext/calc_image_dimensions.rb +34 -0
  80. data/lib/thinreports/basic_report/generator/pdf/prawn_ext/width_of.rb +31 -0
  81. data/lib/thinreports/basic_report/generator/pdf.rb +66 -0
  82. data/lib/thinreports/basic_report/layout/base.rb +48 -0
  83. data/lib/thinreports/basic_report/layout/format.rb +67 -0
  84. data/lib/thinreports/basic_report/layout/legacy_schema.rb +383 -0
  85. data/lib/thinreports/basic_report/layout/version.rb +41 -0
  86. data/lib/thinreports/{layout.rb → basic_report/layout.rb} +6 -4
  87. data/lib/thinreports/basic_report/report/base.rb +173 -0
  88. data/lib/thinreports/basic_report/report/internal.rb +107 -0
  89. data/lib/thinreports/basic_report/report/page.rb +97 -0
  90. data/lib/thinreports/basic_report/report.rb +26 -0
  91. data/lib/thinreports/basic_report.rb +15 -0
  92. data/lib/thinreports/config.rb +1 -1
  93. data/lib/thinreports/section_report/builder/stack_view_builder.rb +0 -2
  94. data/lib/thinreports/section_report.rb +12 -0
  95. data/lib/thinreports/version.rb +1 -1
  96. data/lib/thinreports.rb +2 -13
  97. data/thinreports.gemspec +3 -7
  98. metadata +99 -157
  99. data/Dockerfile +0 -12
  100. data/gemfiles/prawn-2.2.gemfile +0 -5
  101. data/gemfiles/prawn-2.3.gemfile +0 -5
  102. data/gemfiles/prawn-2.4.gemfile +0 -5
  103. data/lib/thinreports/core/errors.rb +0 -60
  104. data/lib/thinreports/core/format/base.rb +0 -89
  105. data/lib/thinreports/core/shape/base/interface.rb +0 -40
  106. data/lib/thinreports/core/shape/base/internal.rb +0 -51
  107. data/lib/thinreports/core/shape/basic/block_format.rb +0 -13
  108. data/lib/thinreports/core/shape/basic/block_interface.rb +0 -32
  109. data/lib/thinreports/core/shape/basic/block_internal.rb +0 -34
  110. data/lib/thinreports/core/shape/basic/format.rb +0 -22
  111. data/lib/thinreports/core/shape/basic/interface.rb +0 -85
  112. data/lib/thinreports/core/shape/basic/internal.rb +0 -26
  113. data/lib/thinreports/core/shape/image_block/format.rb +0 -12
  114. data/lib/thinreports/core/shape/image_block/interface.rb +0 -23
  115. data/lib/thinreports/core/shape/image_block/internal.rb +0 -17
  116. data/lib/thinreports/core/shape/list/format.rb +0 -90
  117. data/lib/thinreports/core/shape/list/manager.rb +0 -229
  118. data/lib/thinreports/core/shape/list/page.rb +0 -110
  119. data/lib/thinreports/core/shape/list/page_state.rb +0 -48
  120. data/lib/thinreports/core/shape/list/section_format.rb +0 -35
  121. data/lib/thinreports/core/shape/list/section_interface.rb +0 -49
  122. data/lib/thinreports/core/shape/list/section_internal.rb +0 -31
  123. data/lib/thinreports/core/shape/manager/format.rb +0 -31
  124. data/lib/thinreports/core/shape/manager/internal.rb +0 -107
  125. data/lib/thinreports/core/shape/manager/target.rb +0 -112
  126. data/lib/thinreports/core/shape/page_number/format.rb +0 -30
  127. data/lib/thinreports/core/shape/page_number/interface.rb +0 -29
  128. data/lib/thinreports/core/shape/page_number/internal.rb +0 -55
  129. data/lib/thinreports/core/shape/stack_view/format.rb +0 -27
  130. data/lib/thinreports/core/shape/stack_view/interface.rb +0 -17
  131. data/lib/thinreports/core/shape/stack_view/internal.rb +0 -22
  132. data/lib/thinreports/core/shape/stack_view/row_format.rb +0 -39
  133. data/lib/thinreports/core/shape/style/base.rb +0 -146
  134. data/lib/thinreports/core/shape/style/basic.rb +0 -22
  135. data/lib/thinreports/core/shape/style/graphic.rb +0 -41
  136. data/lib/thinreports/core/shape/style/text.rb +0 -120
  137. data/lib/thinreports/core/shape/text/format.rb +0 -15
  138. data/lib/thinreports/core/shape/text/interface.rb +0 -18
  139. data/lib/thinreports/core/shape/text/internal.rb +0 -22
  140. data/lib/thinreports/core/shape/text_block/format.rb +0 -41
  141. data/lib/thinreports/core/shape/text_block/formatter/basic.rb +0 -39
  142. data/lib/thinreports/core/shape/text_block/formatter/datetime.rb +0 -23
  143. data/lib/thinreports/core/shape/text_block/formatter/number.rb +0 -67
  144. data/lib/thinreports/core/shape/text_block/formatter/padding.rb +0 -25
  145. data/lib/thinreports/core/shape/text_block/formatter.rb +0 -34
  146. data/lib/thinreports/core/shape/text_block/interface.rb +0 -35
  147. data/lib/thinreports/core/shape/text_block/internal.rb +0 -73
  148. data/lib/thinreports/core/shape.rb +0 -42
  149. data/lib/thinreports/core/utils.rb +0 -45
  150. data/lib/thinreports/generate.rb +0 -11
  151. data/lib/thinreports/generator/pdf/document/draw_shape.rb +0 -106
  152. data/lib/thinreports/generator/pdf/document/draw_template_items.rb +0 -69
  153. data/lib/thinreports/generator/pdf/document/font.rb +0 -88
  154. data/lib/thinreports/generator/pdf/document/graphics/attributes.rb +0 -147
  155. data/lib/thinreports/generator/pdf/document/graphics/basic.rb +0 -135
  156. data/lib/thinreports/generator/pdf/document/graphics/image.rb +0 -98
  157. data/lib/thinreports/generator/pdf/document/graphics/text.rb +0 -178
  158. data/lib/thinreports/generator/pdf/document/graphics.rb +0 -40
  159. data/lib/thinreports/generator/pdf/document/page.rb +0 -94
  160. data/lib/thinreports/generator/pdf/document/parse_color.rb +0 -49
  161. data/lib/thinreports/generator/pdf/document.rb +0 -130
  162. data/lib/thinreports/generator/pdf/drawer/base.rb +0 -48
  163. data/lib/thinreports/generator/pdf/drawer/list.rb +0 -63
  164. data/lib/thinreports/generator/pdf/drawer/list_section.rb +0 -49
  165. data/lib/thinreports/generator/pdf/drawer/page.rb +0 -125
  166. data/lib/thinreports/generator/pdf/prawn_ext/calc_image_dimensions.rb +0 -32
  167. data/lib/thinreports/generator/pdf/prawn_ext/width_of.rb +0 -29
  168. data/lib/thinreports/generator/pdf.rb +0 -63
  169. data/lib/thinreports/layout/base.rb +0 -46
  170. data/lib/thinreports/layout/format.rb +0 -65
  171. data/lib/thinreports/layout/legacy_schema.rb +0 -381
  172. data/lib/thinreports/layout/version.rb +0 -39
  173. data/lib/thinreports/report/base.rb +0 -169
  174. data/lib/thinreports/report/internal.rb +0 -105
  175. data/lib/thinreports/report/page.rb +0 -95
  176. data/lib/thinreports/report.rb +0 -24
  177. data/lib/thinreports/section_report/pdf/renderer/headers_renderer.rb +0 -24
  178. /data/lib/thinreports/{core → basic_report/core}/shape/base.rb +0 -0
  179. /data/lib/thinreports/{core → basic_report/core}/shape/manager.rb +0 -0
  180. /data/lib/thinreports/{core → basic_report/core}/shape/style.rb +0 -0
  181. /data/lib/thinreports/{generator → basic_report/generator}/pdf/prawn_ext.rb +0 -0
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module Basic
8
+ class BlockFormat < Basic::Format
9
+ config_reader :value
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module Basic
8
+ class BlockInterface < Basic::Interface
9
+ # @overload value(val)
10
+ # Set a val
11
+ # @param [Object] val
12
+ # @return [self]
13
+ # @overload value
14
+ # Return the value
15
+ # @return [Object]
16
+ def value(*args)
17
+ if args.empty?
18
+ internal.read_value
19
+ else
20
+ internal.write_value(args.first)
21
+ self
22
+ end
23
+ end
24
+
25
+ # @param [Object] val
26
+ def value=(val)
27
+ value(val)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module Basic
8
+ class BlockInternal < Basic::Internal
9
+ format_delegators :box
10
+
11
+ def style
12
+ @style ||= Style::Basic.new(format)
13
+ end
14
+
15
+ def read_value
16
+ states.key?(:value) ? states[:value] : format.value.dup
17
+ end
18
+ alias value read_value
19
+
20
+ def write_value(val)
21
+ states[:value] = val
22
+ end
23
+
24
+ def real_value
25
+ read_value
26
+ end
27
+
28
+ def type_of?(type_name)
29
+ type_name == :block
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thinreports
4
+ module BasicReport
5
+ module Core
6
+ module Shape
7
+ module Basic
8
+ class Format < Core::Format::Base
9
+ include Utils
10
+
11
+ config_reader :type, :id
12
+ config_reader :style
13
+ config_checker true, :display
14
+ config_reader follow_stretch: %w[follow-stretch]
15
+
16
+ def affect_bottom_margin?
17
+ attributes.fetch('affect-bottom-margin', true)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -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