pdf_paradise 0.3.20

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 (130) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +933 -0
  3. data/bin/automatic_pdf_title +7 -0
  4. data/bin/burst_this_pdf_file +7 -0
  5. data/bin/combine_these_pdf_pages +7 -0
  6. data/bin/compress_via_hexapdf +7 -0
  7. data/bin/convert_markdown_to_pdf +7 -0
  8. data/bin/convert_pdf_to_text +7 -0
  9. data/bin/delete_first_page_of_this_pdf_file +7 -0
  10. data/bin/djvu_to_pdf +7 -0
  11. data/bin/merge_then_open +7 -0
  12. data/bin/n_pages +10 -0
  13. data/bin/open_main_pdf +7 -0
  14. data/bin/pdf_paradise +9 -0
  15. data/bin/rotate_pdf +7 -0
  16. data/bin/set_main_book +7 -0
  17. data/bin/set_title_of_this_pdf_file +15 -0
  18. data/doc/README.gen +871 -0
  19. data/doc/todo/todo.md +13 -0
  20. data/images/Logo_for_the_pdf_paradise_project.avif +0 -0
  21. data/lib/pdf_paradise/base/base.rb +344 -0
  22. data/lib/pdf_paradise/base/colours.rb +67 -0
  23. data/lib/pdf_paradise/colours/colours.rb +27 -0
  24. data/lib/pdf_paradise/commandline/commandline.rb +109 -0
  25. data/lib/pdf_paradise/commandline/help.rb +77 -0
  26. data/lib/pdf_paradise/commandline/menu.rb +173 -0
  27. data/lib/pdf_paradise/compress/compress_this_pdf_file.rb +108 -0
  28. data/lib/pdf_paradise/compress/compress_via_hexapdf.rb +27 -0
  29. data/lib/pdf_paradise/compress/compress_via_qpdf.rb +32 -0
  30. data/lib/pdf_paradise/constants/constants.rb +76 -0
  31. data/lib/pdf_paradise/convert_text_to_pdf.rb +94 -0
  32. data/lib/pdf_paradise/css/project.css +17 -0
  33. data/lib/pdf_paradise/fpdf/README.md +2 -0
  34. data/lib/pdf_paradise/fpdf/bookmark.rb +129 -0
  35. data/lib/pdf_paradise/fpdf/chinese.rb +454 -0
  36. data/lib/pdf_paradise/fpdf/fpdf.rb +1902 -0
  37. data/lib/pdf_paradise/fpdf/fpdf_eps.rb +138 -0
  38. data/lib/pdf_paradise/fpdf/makefont.rb +1794 -0
  39. data/lib/pdf_paradise/gui/README.md +6 -0
  40. data/lib/pdf_paradise/gui/fox/split_pdf_file.rb +77 -0
  41. data/lib/pdf_paradise/gui/gtk2/pdf_viewer/pdf_viewer.rb +34 -0
  42. data/lib/pdf_paradise/gui/gtk2/split_pdf_file/split_pdf_file.rb +34 -0
  43. data/lib/pdf_paradise/gui/gtk2/statistics_widget/statistics_widget.rb +34 -0
  44. data/lib/pdf_paradise/gui/gtk3/controller/controller.rb +214 -0
  45. data/lib/pdf_paradise/gui/gtk3/pdf_viewer/pdf_viewer.rb +34 -0
  46. data/lib/pdf_paradise/gui/gtk3/split_pdf_file/split_pdf_file.rb +34 -0
  47. data/lib/pdf_paradise/gui/jruby/delete_the_first_or_the_last_page_of_this_pdf_file/delete_the_first_or_the_last_page_of_this_pdf_file.rb +167 -0
  48. data/lib/pdf_paradise/gui/jruby/remove_the_first_page_of_this_pdf_file/remove_the_first_page_of_this_pdf_file.rb +103 -0
  49. data/lib/pdf_paradise/gui/libui/extract_all_images_from_this_pdf_file/extract_all_images_from_this_pdf_file.rb +223 -0
  50. data/lib/pdf_paradise/gui/libui/remove_the_first_page_of_this_pdf_file/remove_the_first_page_of_this_pdf_file.rb +267 -0
  51. data/lib/pdf_paradise/gui/libui/rotate_pdf_file/rotate_pdf_file.rb +219 -0
  52. data/lib/pdf_paradise/gui/libui/statistics_widget/statistics_widget.rb +233 -0
  53. data/lib/pdf_paradise/gui/shared_code/pdf_viewer/pdf_viewer.css +5 -0
  54. data/lib/pdf_paradise/gui/shared_code/pdf_viewer/pdf_viewer_module.rb +287 -0
  55. data/lib/pdf_paradise/gui/shared_code/remove_the_first_page_of_this_pdf_file_module/remove_the_first_page_of_this_pdf_file_module.rb +31 -0
  56. data/lib/pdf_paradise/gui/shared_code/split_pdf_file/split_pdf_file_module.rb +295 -0
  57. data/lib/pdf_paradise/gui/universal_widgets/convert_pdf_to_text/convert_pdf_to_text.rb +366 -0
  58. data/lib/pdf_paradise/gui/universal_widgets/delete_the_first_or_the_last_page_of_this_pdf_file/delete_the_first_or_the_last_page_of_this_pdf_file.rb +776 -0
  59. data/lib/pdf_paradise/gui/universal_widgets/statistics_widget/statistics_widget.rb +407 -0
  60. data/lib/pdf_paradise/gui/universal_widgets/to_pdf/to_pdf.rb +351 -0
  61. data/lib/pdf_paradise/hexapdf/001_rainbow_pattern_example.rb +0 -0
  62. data/lib/pdf_paradise/hexapdf/hexapdf.rb +123 -0
  63. data/lib/pdf_paradise/images/PDF_PARADISE_LOGO.png +0 -0
  64. data/lib/pdf_paradise/main_pdf/main_pdf.rb +474 -0
  65. data/lib/pdf_paradise/merge_pdf/menu.rb +63 -0
  66. data/lib/pdf_paradise/merge_pdf/merge_pdf.rb +307 -0
  67. data/lib/pdf_paradise/merge_pdf_namespace.rb +9 -0
  68. data/lib/pdf_paradise/merge_then_open/merge_then_open.rb +105 -0
  69. data/lib/pdf_paradise/prawn_addons/README.md +2 -0
  70. data/lib/pdf_paradise/prawn_addons/prawn_addons.rb +17 -0
  71. data/lib/pdf_paradise/project/project.rb +22 -0
  72. data/lib/pdf_paradise/remove_pdf_password.rb +391 -0
  73. data/lib/pdf_paradise/requires/batch_require_toplevel_files.rb +22 -0
  74. data/lib/pdf_paradise/requires/colours.rb +11 -0
  75. data/lib/pdf_paradise/requires/colours_and_esystem_and_save_file_and_fileutils_and_opn.rb +13 -0
  76. data/lib/pdf_paradise/requires/esystem_and_colours.rb +11 -0
  77. data/lib/pdf_paradise/requires/esystem_and_opn_and_colours.rb +10 -0
  78. data/lib/pdf_paradise/requires/require_the_whole_project.rb +30 -0
  79. data/lib/pdf_paradise/requires/require_utility_scripts.rb +9 -0
  80. data/lib/pdf_paradise/set_main_book.rb +156 -0
  81. data/lib/pdf_paradise/set_pdf_title.rb +220 -0
  82. data/lib/pdf_paradise/sinatra/embeddable_interface.rb +389 -0
  83. data/lib/pdf_paradise/toplevel_methods/convert_epub_to_pdf.rb +27 -0
  84. data/lib/pdf_paradise/toplevel_methods/convert_markdown_to_pdf.rb +45 -0
  85. data/lib/pdf_paradise/toplevel_methods/convert_ppt_to_pdf.rb +35 -0
  86. data/lib/pdf_paradise/toplevel_methods/e.rb +16 -0
  87. data/lib/pdf_paradise/toplevel_methods/esystem.rb +20 -0
  88. data/lib/pdf_paradise/toplevel_methods/misc.rb +228 -0
  89. data/lib/pdf_paradise/toplevel_methods/number_pages.rb +38 -0
  90. data/lib/pdf_paradise/toplevel_methods/opened_pdf_files.rb +221 -0
  91. data/lib/pdf_paradise/toplevel_methods/query_pdf_title.rb +201 -0
  92. data/lib/pdf_paradise/toplevel_methods/reduce_size_of_this_pdf_file.rb +46 -0
  93. data/lib/pdf_paradise/toplevel_methods/roebe.rb +17 -0
  94. data/lib/pdf_paradise/toplevel_methods/to_pdf.rb +12 -0
  95. data/lib/pdf_paradise/utility_scripts/README.md +3 -0
  96. data/lib/pdf_paradise/utility_scripts/automatic_pdf_title.rb +104 -0
  97. data/lib/pdf_paradise/utility_scripts/check_syntax_of_pdf_files.rb +106 -0
  98. data/lib/pdf_paradise/utility_scripts/combine_these_pdf_pages.rb +118 -0
  99. data/lib/pdf_paradise/utility_scripts/convert_pdf_to_text.rb +179 -0
  100. data/lib/pdf_paradise/utility_scripts/delete_last_page_of_this_pdf_file.rb +180 -0
  101. data/lib/pdf_paradise/utility_scripts/delete_the_first_page_of_this_pdf_file/delete_the_first_page_of_this_pdf_file.rb +429 -0
  102. data/lib/pdf_paradise/utility_scripts/delete_this_page_of_this_pdf_file.rb +356 -0
  103. data/lib/pdf_paradise/utility_scripts/djvu_to_pdf.rb +87 -0
  104. data/lib/pdf_paradise/utility_scripts/extract_all_images_from_this_pdf_file.rb +129 -0
  105. data/lib/pdf_paradise/utility_scripts/extract_pdf_page.rb +283 -0
  106. data/lib/pdf_paradise/utility_scripts/pdf_file_n_total_pages.rb +348 -0
  107. data/lib/pdf_paradise/utility_scripts/pdf_optimizer.rb +111 -0
  108. data/lib/pdf_paradise/utility_scripts/pdf_statistics.rb +148 -0
  109. data/lib/pdf_paradise/utility_scripts/pdf_to_html.rb +75 -0
  110. data/lib/pdf_paradise/utility_scripts/remove_images.rb +110 -0
  111. data/lib/pdf_paradise/utility_scripts/rotate_pdf_file.rb +303 -0
  112. data/lib/pdf_paradise/utility_scripts/split_pdf.rb +364 -0
  113. data/lib/pdf_paradise/utility_scripts/to_pdf.rb +130 -0
  114. data/lib/pdf_paradise/utility_scripts/to_qdf.rb +66 -0
  115. data/lib/pdf_paradise/version/version.rb +19 -0
  116. data/lib/pdf_paradise/www/README.md +2 -0
  117. data/lib/pdf_paradise/www/sinatra/app.rb +304 -0
  118. data/lib/pdf_paradise/yaml/working_on_these_pdf_files.yml +4 -0
  119. data/lib/pdf_paradise.rb +5 -0
  120. data/pdf_paradise.gemspec +61 -0
  121. data/test/fpdf/001_minimal_example.rb +12 -0
  122. data/test/fpdf/002.pdf +0 -0
  123. data/test/fpdf/002_header_and_footer_example.rb +64 -0
  124. data/test/fpdf/003.pdf +98 -0
  125. data/test/fpdf/003_justified_paragraphs.rb +96 -0
  126. data/test/fpdf/file1.md +3 -0
  127. data/test/fpdf/file2.md +3 -0
  128. data/test/fpdf/test.pdf +0 -0
  129. data/test/testing_pdf_paradise.rb +12 -0
  130. metadata +239 -0
@@ -0,0 +1,776 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # === PdfParadise::GUI::UniversalWidgets::DeleteTheFirstOrTheLastPageOfThisPdfFile
6
+ #
7
+ # This class is a simple gtk-GUI wrapper over the remove-first-page and
8
+ # the remove-last-page functionality of the PdfParadise project.
9
+ #
10
+ # It also serves as a prototype for the jruby-SWING wrapper.
11
+ #
12
+ # Usage example:
13
+ #
14
+ # PdfParadise::GUI::UniversalWidgets::DeleteTheFirstOrTheLastPageOfThisPdfFile.new(ARGV)
15
+ #
16
+ # =========================================================================== #
17
+ # require 'pdf_paradise/gui/universal_widgets/statistics_widget/statistics_widget.rb'
18
+ # =========================================================================== #
19
+ require 'pdf_paradise/base/base.rb'
20
+
21
+ module PdfParadise
22
+
23
+ module GUI
24
+
25
+ module UniversalWidgets
26
+
27
+ class DeleteTheFirstOrTheLastPageOfThisPdfFile < ::PdfParadise::Base # === PdfParadise::GUI::UniversalWidgets::DeleteTheFirstOrTheLastPageOfThisPdfFile
28
+
29
+ require 'universal_widgets/base_module/base_module.rb'
30
+ include ::UniversalWidgets::BaseModule
31
+
32
+ require 'pdf_paradise/utility_scripts/delete_the_first_page_of_this_pdf_file/delete_the_first_page_of_this_pdf_file.rb'
33
+ require 'pdf_paradise/utility_scripts/delete_last_page_of_this_pdf_file.rb'
34
+ require 'pdf_paradise/utility_scripts/delete_this_page_of_this_pdf_file.rb'
35
+ require 'pdf_paradise/utility_scripts/pdf_file_n_total_pages.rb'
36
+
37
+ # ========================================================================= #
38
+ # === TITLE
39
+ # ========================================================================= #
40
+ TITLE = 'Remove a specific page from a .pdf file.'
41
+
42
+ # ========================================================================= #
43
+ # === DENOTE_WHICH_PDF_PAGE_IS_TO_BE_REMOVED
44
+ # ========================================================================= #
45
+ DENOTE_WHICH_PDF_PAGE_IS_TO_BE_REMOVED =
46
+ 'Denote which .pdf page (as a number) is to be removed '
47
+
48
+ # ========================================================================= #
49
+ # === FONT_SIZE_LARGE
50
+ # ========================================================================= #
51
+ FONT_SIZE_LARGE = 30
52
+
53
+ # ========================================================================= #
54
+ # === FONT_SIZE
55
+ # ========================================================================= #
56
+ FONT_SIZE = 18
57
+
58
+ # ========================================================================= #
59
+ # === USE_THIS_FONT
60
+ # ========================================================================= #
61
+ USE_THIS_FONT = :dejavu_condensed_24
62
+
63
+ # ========================================================================= #
64
+ # === SMALLER_FONT
65
+ # ========================================================================= #
66
+ SMALLER_FONT = :dejavu_condensed_22
67
+
68
+ # ========================================================================= #
69
+ # === HEIGHT_FOR_THE_SECOND_ENTRY
70
+ # ========================================================================= #
71
+ HEIGHT_FOR_THE_SECOND_ENTRY = 40
72
+
73
+ # ========================================================================= #
74
+ # === LABEL_SET_THE_PATH_TO_THE_PDF_FILE_BELOW_THIS_TEXT_HERE
75
+ # ========================================================================= #
76
+ LABEL_SET_THE_PATH_TO_THE_PDF_FILE_BELOW_THIS_TEXT_HERE =
77
+ 'Set the path to the .pdf file below this text here.'
78
+
79
+ # ========================================================================= #
80
+ # === ARRAY_ADD_THESE_SHORTCUT_FOLDERS
81
+ # ========================================================================= #
82
+ ARRAY_ADD_THESE_SHORTCUT_FOLDERS = [
83
+ '/',
84
+ '/Depot/j/',
85
+ '/Depot/PDF/'
86
+ ]
87
+
88
+ # ========================================================================= #
89
+ # === USE_THIS_FONT_FOR_THE_DISPLAY_AREA
90
+ # ========================================================================= #
91
+ USE_THIS_FONT_FOR_THE_DISPLAY_AREA = 'DejaVu Sans Mono 18' # :hack_18
92
+
93
+ # ========================================================================= #
94
+ # === WIDTH
95
+ # ========================================================================= #
96
+ WIDTH = '52% or minimum 1500px'
97
+
98
+ # ========================================================================= #
99
+ # === HEIGHT
100
+ # ========================================================================= #
101
+ HEIGHT = '45% or minimum 500px'
102
+
103
+ # ========================================================================= #
104
+ # === LARGER_FONT
105
+ # ========================================================================= #
106
+ LARGER_FONT = :hack_24
107
+
108
+ # ========================================================================= #
109
+ # === initialize
110
+ # ========================================================================= #
111
+ def initialize(
112
+ commandline_arguments = nil,
113
+ run_already = true
114
+ )
115
+ super(:vertical) if use_gtk3?
116
+ determine_the_GUI_to_be_used(commandline_arguments) # This must come first, even before reset().
117
+ reset
118
+ set_commandline_arguments(
119
+ commandline_arguments
120
+ )
121
+ run if run_already
122
+ end
123
+
124
+ # ========================================================================= #
125
+ # === reset (reset tag)
126
+ # ========================================================================= #
127
+ def reset
128
+ super() if respond_to?(:super)
129
+ reset_the_base_module
130
+ reset_the_internal_variables
131
+ infer_the_namespace
132
+ # ======================================================================= #
133
+ # === @configuration
134
+ # ======================================================================= #
135
+ @configuration = [true, __dir__, namespace?]
136
+ # ======================================================================= #
137
+ # === Set the title, width, height and the font in use.
138
+ # ======================================================================= #
139
+ title_width_height_font(TITLE, WIDTH, HEIGHT, USE_THIS_FONT)
140
+ if use_gtk3?
141
+ append_project_css_file
142
+ use_gtk_paradise_project_css_file
143
+ end
144
+ infer_the_size_automatically
145
+ end
146
+
147
+ # ========================================================================= #
148
+ # === populate_the_grid (grid tag)
149
+ # ========================================================================= #
150
+ def populate_the_grid(grid)
151
+ grid.full_row(return_set_the_path_to_the_pdf_file_below_widget)
152
+ grid.full_row(return_text_and_entry_remove_this_pdf_page)
153
+ grid.full_row(checkbox_shall_we_overwrite_the_original_pdf_file?)
154
+ grid.full_row(create_and_then_return_the_label_that_shows_how_many_pages_are_in_the_given_pdf_file)
155
+ grid.full_row(text_for_notifications?)
156
+ end
157
+
158
+ # ========================================================================= #
159
+ # === create_the_skeleton (create tag, skeleton tag)
160
+ # ========================================================================= #
161
+ def create_the_skeleton
162
+ create_the_entries
163
+ create_the_buttons
164
+ create_the_labels
165
+ create_the_checkboxes
166
+ end
167
+
168
+ # ========================================================================= #
169
+ # === connect_the_skeleton (connect tag)
170
+ # ========================================================================= #
171
+ def connect_the_skeleton
172
+ abort_on_exception
173
+
174
+ outer_vbox = create_vbox
175
+
176
+ grid = default_grid # grid tag
177
+ grid.uniform_spacing(18)
178
+ populate_the_grid(grid)
179
+ right_side = create_vbox # right tag
180
+ right_side.minimal(@button_remove_the_first_page_of_the_pdf_file, 2)
181
+ right_side.minimal(@button_remove_the_last_page_of_the_pdf_file, 2)
182
+ right_side.minimal(@button_remove_the_specified_page_of_the_pdf_file, 2)
183
+ right_side.minimal(@button_pdf_viewer, 2)
184
+ right_side.minimal(@button_file_chooser, 2)
185
+ right_side.show_all
186
+ _ = drag_from_left_to_right(
187
+ grid,
188
+ right_side
189
+ )
190
+ outer_vbox.minimal(_)
191
+
192
+ window = create_window_or_runner(
193
+ widget: outer_vbox,
194
+ width: width?,
195
+ height: height?,
196
+ title: title?,
197
+ font: font?
198
+ )
199
+
200
+ window.set_padding(padding?)
201
+ window.set_border_size(border_size?)
202
+ window.show_all
203
+ Thread.new {
204
+ sleep 0.001
205
+ main_entry?.do_focus
206
+ }
207
+ do_parse_the_commandline_arguments
208
+ run_main
209
+ end
210
+
211
+ # ========================================================================= #
212
+ # === create_the_file_chooser_button
213
+ # ========================================================================= #
214
+ def create_the_file_chooser_button
215
+ # ======================================================================= #
216
+ # === @button_file_chooser
217
+ # ======================================================================= #
218
+ @button_file_chooser = bold_button('🗄️ _Choose a file', self, :use_mnemonics) {
219
+ :open_file_chooser_dialog
220
+ }
221
+ @button_file_chooser.hint =
222
+ 'Click this button to select a file. It will then appear in the '\
223
+ 'entry on the top-left part of this widget.'
224
+ @button_file_chooser.clear_background
225
+ @button_file_chooser.skyblue
226
+ @button_file_chooser.bblack2
227
+ end
228
+
229
+ # ========================================================================= #
230
+ # === create_the_remove_the_specified_page_of_the_pdf_file_button
231
+ # ========================================================================= #
232
+ def create_the_remove_the_specified_page_of_the_pdf_file_button
233
+ _ = bold_button('Remove the _specified page')
234
+ _.clear_background
235
+ _.skyblue
236
+ _.bblack2
237
+ _.do_use_mnemonic
238
+ _.hint =
239
+ " <b>Click</b> on this button to remove the specified page of the pdf file.\n"\
240
+ "Do not forget to make sure that the .pdf file exists at that location, in "\
241
+ "the top-left entry; and make sure that a number is input in the second "\
242
+ "entry below."
243
+ _.on_clicked {
244
+ do_determine_how_many_pages_are_in_the_pdf_file
245
+ do_remove_the_specified_page_of_the_pdf_file
246
+ do_determine_how_many_pages_are_in_the_pdf_file
247
+ }
248
+ @button_remove_the_specified_page_of_the_pdf_file = _
249
+ end
250
+
251
+ # ========================================================================= #
252
+ # === create_the_remove_the_last_page_of_the_pdf_file_button
253
+ # ========================================================================= #
254
+ def create_the_remove_the_last_page_of_the_pdf_file_button
255
+ # ======================================================================= #
256
+ # === @button_remove_the_last_page_of_the_pdf_file
257
+ # ======================================================================= #
258
+ @button_remove_the_last_page_of_the_pdf_file = bold_button('Remove the _last page')
259
+ @button_remove_the_last_page_of_the_pdf_file.clear_background
260
+ @button_remove_the_last_page_of_the_pdf_file.skyblue
261
+ @button_remove_the_last_page_of_the_pdf_file.bblack2
262
+ @button_remove_the_last_page_of_the_pdf_file.do_use_mnemonic
263
+ @button_remove_the_last_page_of_the_pdf_file.hint =
264
+ " <b>Click</b> on this button to remove the last page of the pdf file.\n"\
265
+ "Do not forget to make sure that the .pdf file exists at that location."
266
+ @button_remove_the_last_page_of_the_pdf_file.on_clicked {
267
+ do_determine_how_many_pages_are_in_the_pdf_file
268
+ do_remove_the_last_page_of_the_pdf_file
269
+ do_determine_how_many_pages_are_in_the_pdf_file
270
+ }
271
+ end
272
+
273
+ # ========================================================================= #
274
+ # === do_determine_how_many_pages_are_in_the_pdf_file
275
+ #
276
+ # This method should ideally be called only when the .pdf file at hand
277
+ # exists.
278
+ # ========================================================================= #
279
+ def do_determine_how_many_pages_are_in_the_pdf_file
280
+ main_entry = main_entry?
281
+ if main_entry and main_entry.respond_to?(:text?)
282
+ this_file = main_entry?.text?.to_s
283
+ if File.exist? this_file
284
+ n_pages = PdfParadise.n_pages_in_this_pdf_file?(this_file)
285
+ _ = 'The <b>.pdf</b> file at <b>'+this_file+'</b> contains '\
286
+ '<b>'+n_pages.to_s+'</b> pages.'
287
+ @label_n_pages_in_the_pdf_file.set_text(_)
288
+ else
289
+ @label_n_pages_in_the_pdf_file.set_text('')
290
+ end
291
+ @label_n_pages_in_the_pdf_file.do_markify
292
+ @label_n_pages_in_the_pdf_file.make_selectable
293
+ end
294
+ end; alias update_n_pages do_determine_how_many_pages_are_in_the_pdf_file # === update_n_pages
295
+
296
+ # ========================================================================= #
297
+ # === do_remove_this_page
298
+ # ========================================================================= #
299
+ def do_remove_this_page(
300
+ i = entry_remove_this_pdf_page?.text?,
301
+ target_file = entry_for_the_path_to_the_pdf_file?.text.to_s
302
+ )
303
+ if File.exist?(target_file)
304
+ PdfParadise.remove_this_page_of_that_pdf_file(
305
+ i, target_file
306
+ )
307
+ update_all_done_finished_at
308
+ else
309
+ no_file_was_found_at(target_file)
310
+ end
311
+ end
312
+
313
+ # ========================================================================= #
314
+ # === do_remove_the_first_page_of_the_pdf_file
315
+ #
316
+ # This is the main action of this class.
317
+ # ========================================================================= #
318
+ def do_remove_the_first_page_of_the_pdf_file
319
+ e 'Now removing the first .pdf page.'
320
+ target_file = entry_for_the_path_to_the_pdf_file?.text?
321
+ if File.exist?(target_file)
322
+ PdfParadise.remove_the_first_page_of_this_pdf_file(
323
+ target_file
324
+ )
325
+ # ===================================================================== #
326
+ # Notify the user that we finished here.
327
+ # ===================================================================== #
328
+ update_all_done_finished_at
329
+ else
330
+ no_file_was_found_at(target_file)
331
+ end
332
+ end
333
+
334
+ # ========================================================================= #
335
+ # === update_all_done_finished_at
336
+ # ========================================================================= #
337
+ def update_all_done_finished_at
338
+ @text_for_notifications.set_text(
339
+ 'All done! Finished at <b>'+Time.now.to_s+'</b>'
340
+ )
341
+ @text_for_notifications.do_markify
342
+ @text_for_notifications.make_selectable
343
+ end
344
+
345
+ # ========================================================================= #
346
+ # === do_parse_the_commandline_arguments
347
+ # ========================================================================= #
348
+ def do_parse_the_commandline_arguments
349
+ commandline_arguments?.each {|this_entry|
350
+ if this_entry and File.exist?(this_entry)
351
+ this_entry = File.absolute_path(this_entry)
352
+ set_use_this_pdf_file(this_entry)
353
+ end
354
+ }
355
+ end
356
+
357
+ # ========================================================================= #
358
+ # === do_remove_the_specified_page_of_the_pdf_file
359
+ # ========================================================================= #
360
+ def do_remove_the_specified_page_of_the_pdf_file
361
+ _ = main_entry?.text?
362
+ this_page = which_page?
363
+ if File.exist? _
364
+ update_n_pages
365
+ if checkbox_shall_we_overwrite_the_original_pdf_file?.is_active?
366
+ PdfParadise.remove_this_page_from_that_pdf_file(this_page, _) {
367
+ :do_not_overwrite_the_original_pdf_file
368
+ }
369
+ else
370
+ PdfParadise.remove_this_page_from_that_pdf_file(this_page, _)
371
+ end
372
+ update_n_pages
373
+ end
374
+ end
375
+
376
+ # ========================================================================= #
377
+ # === checkbox_shall_we_overwrite_the_original_pdf_file
378
+ # ========================================================================= #
379
+ def checkbox_shall_we_overwrite_the_original_pdf_file?
380
+ @checkbox_shall_we_overwrite_the_original_pdf_file
381
+ end; alias main_checkbox? checkbox_shall_we_overwrite_the_original_pdf_file? # === main_checkbox?
382
+
383
+ # ========================================================================= #
384
+ # === create_the_checkboxes
385
+ # ========================================================================= #
386
+ def create_the_checkboxes
387
+ # ======================================================================= #
388
+ # === @checkbox_shall_we_overwrite_the_original_pdf_file
389
+ # ======================================================================= #
390
+ @checkbox_shall_we_overwrite_the_original_pdf_file = create_checkbox(:is_checked)
391
+ @checkbox_shall_we_overwrite_the_original_pdf_file.set_text(
392
+ 'overwrite the original .pdf file'
393
+ )
394
+ @checkbox_shall_we_overwrite_the_original_pdf_file.hint =
395
+ 'If this checkbox is active, then the original .pdf file '\
396
+ 'will NOT be overwritten. This is sometimes necessary, such as '\
397
+ 'on windows if you lack proper permission to do the file operation '\
398
+ 'at hand.'
399
+ end
400
+
401
+ # ========================================================================= #
402
+ # === return_text_and_entry_remove_this_pdf_page
403
+ # ========================================================================= #
404
+ def return_text_and_entry_remove_this_pdf_page
405
+ _ = create_vbox
406
+ _.minimal(
407
+ left_aligned_bold_text(
408
+ DENOTE_WHICH_PDF_PAGE_IS_TO_BE_REMOVED
409
+ ), 4
410
+ )
411
+ mini_hbox = create_hbox
412
+ mini_hbox.maximal(@entry_remove_this_pdf_page, 4)
413
+ mini_hbox.minimal(@button_remove_the_specified_page, 4)
414
+ _.maximal(mini_hbox)
415
+ return _
416
+ end
417
+
418
+ # ========================================================================= #
419
+ # === return_set_the_path_to_the_pdf_file_below_widget
420
+ # ========================================================================= #
421
+ def return_set_the_path_to_the_pdf_file_below_widget
422
+ _ = create_vbox
423
+ create_the_text_above_the_main_entry
424
+ _.minimal(@text_above_the_main_entry, 4)
425
+ _.minimal(main_entry?, 4)
426
+ return _
427
+ end
428
+
429
+ # ========================================================================= #
430
+ # === open_file_chooser_dialog (open tag)
431
+ # ========================================================================= #
432
+ def open_file_chooser_dialog
433
+ current_directory = return_pwd
434
+ if is_on_roebe? and File.directory?('/Depot/j/')
435
+ current_directory = '/Depot/j/'
436
+ end
437
+ filename = ::Gtk.select_file(parent_widget?) {{
438
+ current_directory: current_directory,
439
+ show_hidden: true,
440
+ extra_widget: @extra_button,
441
+ add_these_shortcut_folders: ARRAY_ADD_THESE_SHORTCUT_FOLDERS,
442
+ use_this_file_filter: '*.pdf'
443
+ }}
444
+ if filename and filename.end_with? '.pdf'
445
+ entry_for_the_path_to_the_pdf_file?.set_text(filename.to_s)
446
+ do_determine_how_many_pages_are_in_the_pdf_file
447
+ else
448
+ bold_popover_message = bold_text(
449
+ 'Please assign an existing .pdf file in the top-left entry.'
450
+ )
451
+ bold_popover_message.set_font(default_font?)
452
+ popover_message(
453
+ bold_popover_message,
454
+ main_entry?
455
+ ).popup
456
+ end
457
+ end
458
+
459
+ # ========================================================================= #
460
+ # === which_page?
461
+ # ========================================================================= #
462
+ def which_page?
463
+ entry_remove_this_pdf_page?.text?.to_i
464
+ end
465
+
466
+ # ========================================================================= #
467
+ # === entry_for_the_path_to_the_pdf_file?
468
+ # ========================================================================= #
469
+ def entry_for_the_path_to_the_pdf_file?
470
+ @entry_for_the_path_to_the_pdf_file
471
+ end; alias main_entry? entry_for_the_path_to_the_pdf_file? # === main_entry?
472
+ alias top_entry? entry_for_the_path_to_the_pdf_file? # === top_entry?
473
+
474
+ # ========================================================================= #
475
+ # === set_use_this_pdf_file
476
+ # ========================================================================= #
477
+ def set_use_this_pdf_file(
478
+ i, main_entry = main_entry?
479
+ )
480
+ main_entry.set_text(i.to_s) if main_entry
481
+ end
482
+
483
+ # ========================================================================= #
484
+ # === padding?
485
+ # ========================================================================= #
486
+ def padding?
487
+ 4
488
+ end
489
+
490
+ # ========================================================================= #
491
+ # === border_size?
492
+ # ========================================================================= #
493
+ def border_size?
494
+ 2
495
+ end
496
+
497
+ # ========================================================================= #
498
+ # === entry_remove_this_pdf_page?
499
+ # ========================================================================= #
500
+ def entry_remove_this_pdf_page?
501
+ @entry_remove_this_pdf_page
502
+ end
503
+
504
+ # ========================================================================= #
505
+ # === default_font?
506
+ # ========================================================================= #
507
+ def default_font?
508
+ USE_THIS_FONT
509
+ end
510
+
511
+ # ========================================================================= #
512
+ # === create_the_labels
513
+ # ========================================================================= #
514
+ def create_the_labels
515
+ # ======================================================================= #
516
+ # === @text_for_notifications
517
+ # ======================================================================= #
518
+ @text_for_notifications = text
519
+ end
520
+
521
+ # ========================================================================= #
522
+ # === text_for_notifications?
523
+ # ========================================================================= #
524
+ def text_for_notifications?
525
+ @text_for_notifications
526
+ end
527
+
528
+ # ========================================================================= #
529
+ # === create_the_entries (entries tag)
530
+ # ========================================================================= #
531
+ def create_the_entries
532
+ # ======================================================================= #
533
+ # === @entry_for_the_path_to_the_pdf_file
534
+ # ======================================================================= #
535
+ _ = create_entry('')
536
+ _.highlight_on_click_event
537
+ _.add_css_class('BG_floralwhite')
538
+ _.pad4px
539
+ _.width_height(200, HEIGHT_FOR_THE_SECOND_ENTRY)
540
+ @entry_for_the_path_to_the_pdf_file = _
541
+ # ======================================================================= #
542
+ # === @entry_remove_this_pdf_page
543
+ # ======================================================================= #
544
+ @entry_remove_this_pdf_page = create_entry
545
+ @entry_remove_this_pdf_page.highlight_on_click_event
546
+ @entry_remove_this_pdf_page.bblack1
547
+ @entry_remove_this_pdf_page.add_css_class(
548
+ 'BG_floralwhite'
549
+ )
550
+ @entry_remove_this_pdf_page.align_to_the_center
551
+ @entry_remove_this_pdf_page.set_size_request(160, HEIGHT_FOR_THE_SECOND_ENTRY)
552
+ end; alias create_entries create_the_entries # === create_entries
553
+
554
+ # ========================================================================= #
555
+ # === button_remove_the_specified_page?
556
+ # ========================================================================= #
557
+ def button_remove_the_specified_page?
558
+ @button_remove_the_specified_page
559
+ end
560
+
561
+ # ========================================================================= #
562
+ # === parent_widget?
563
+ # ========================================================================= #
564
+ def parent_widget?
565
+ @parent_widget
566
+ end
567
+
568
+ # ========================================================================= #
569
+ # === set_parent_widget
570
+ # ========================================================================= #
571
+ def set_parent_widget(i)
572
+ @parent_widget = i
573
+ end
574
+
575
+ # ========================================================================= #
576
+ # === do_remove_the_last_page_of_the_pdf_file
577
+ # ========================================================================= #
578
+ def do_remove_the_last_page_of_the_pdf_file
579
+ e 'Now removing the last .pdf page.'
580
+ target_file = entry_for_the_path_to_the_pdf_file?.text.to_s
581
+ if File.exist?(target_file)
582
+ PdfParadise.remove_the_last_page_of_this_pdf_file(
583
+ target_file
584
+ )
585
+ # ===================================================================== #
586
+ # Notify the user that we finished here.
587
+ # ===================================================================== #
588
+ update_all_done_finished_at
589
+ else
590
+ no_file_was_found_at(target_file)
591
+ end
592
+ end
593
+
594
+ # ========================================================================= #
595
+ # === create_the_text_above_the_main_entry
596
+ # ========================================================================= #
597
+ def create_the_text_above_the_main_entry
598
+ # ======================================================================= #
599
+ # === @text_above_the_main_entry
600
+ # ======================================================================= #
601
+ @text_above_the_main_entry = bold_label(
602
+ LABEL_SET_THE_PATH_TO_THE_PDF_FILE_BELOW_THIS_TEXT_HERE
603
+ ) {{
604
+ tooltip: 'You need to supply the path to the .pdf file '\
605
+ 'into the entry below this text.'
606
+ }}
607
+ end
608
+
609
+ # ========================================================================= #
610
+ # === create_the_buttons (buttons tag)
611
+ #
612
+ # This method can be used to create all buttons in this small application.
613
+ # ========================================================================= #
614
+ def create_the_buttons
615
+ create_the_open_in_pdf_viewer_button
616
+ # ======================================================================= #
617
+ # === @button_remove_the_first_page_of_the_pdf_file
618
+ # ======================================================================= #
619
+ create_the_remove_the_first_page_of_the_pdf_file_button
620
+ # ======================================================================= #
621
+ # === @button_remove_the_last_page_of_the_pdf_file
622
+ # ======================================================================= #
623
+ create_the_remove_the_last_page_of_the_pdf_file_button
624
+ create_the_remove_the_specified_page_of_the_pdf_file_button
625
+ create_the_file_chooser_button
626
+ # ======================================================================= #
627
+ # === @button_remove_the_specified_page
628
+ # ======================================================================= #
629
+ create_the_remove_the_specified_page_button
630
+ # ======================================================================= #
631
+ # === @extra_button
632
+ # ======================================================================= #
633
+ @extra_button = button('_Extra button')
634
+ @extra_button.on_clicked { e ' > Extra button was clicked' }
635
+ end; alias create_buttons create_the_buttons # === create_buttons
636
+
637
+ # ========================================================================= #
638
+ # === create_the_remove_the_specified_page_button
639
+ # ========================================================================= #
640
+ def create_the_remove_the_specified_page_button
641
+ @button_remove_the_specified_page = button('🗙')
642
+ @button_remove_the_specified_page.hint =
643
+ 'Click this button in order to remove the specified page '\
644
+ 'from the .pdf document at hand.'
645
+ @button_remove_the_specified_page.on_clicked {
646
+ do_determine_how_many_pages_are_in_the_pdf_file
647
+ do_remove_this_page(entry_remove_this_pdf_page?.text?)
648
+ do_determine_how_many_pages_are_in_the_pdf_file
649
+ }
650
+ @button_remove_the_specified_page.set_size_request(100, HEIGHT_FOR_THE_SECOND_ENTRY)
651
+ @button_remove_the_specified_page.bblack1
652
+ @button_remove_the_specified_page.disallow_resizing
653
+ return @button_remove_the_specified_page
654
+ end
655
+
656
+ # ========================================================================= #
657
+ # === create_the_remove_the_first_page_of_the_pdf_file_button
658
+ # ========================================================================= #
659
+ def create_the_remove_the_first_page_of_the_pdf_file_button
660
+ _ = bold_button('Remove the _first page')
661
+ _.clear_background
662
+ _.skyblue
663
+ _.bblack2
664
+ _.do_use_mnemonic
665
+ _.hint =
666
+ "<b>Click</b> on this button to remove the first page of the "\
667
+ "designated <b>.pdf</b> file.\n\n"\
668
+ "Do not forget to make sure that the .pdf file exists at that "\
669
+ "location.\n"\
670
+ "Note that the program called qpdf has to be installed as well."
671
+ _.on_clicked {
672
+ do_determine_how_many_pages_are_in_the_pdf_file
673
+ do_remove_the_first_page_of_the_pdf_file
674
+ do_determine_how_many_pages_are_in_the_pdf_file
675
+ }
676
+ @button_remove_the_first_page_of_the_pdf_file = _
677
+ end
678
+
679
+ # ========================================================================= #
680
+ # === create_and_then_return_the_label_that_shows_how_many_pages_are_in_the_given_pdf_file
681
+ # ========================================================================= #
682
+ def create_and_then_return_the_label_that_shows_how_many_pages_are_in_the_given_pdf_file
683
+ @label_n_pages_in_the_pdf_file = text
684
+ return @label_n_pages_in_the_pdf_file
685
+ end
686
+
687
+ # ========================================================================= #
688
+ # === create_the_open_in_pdf_viewer_button
689
+ # ========================================================================= #
690
+ def create_the_open_in_pdf_viewer_button
691
+ # ======================================================================= #
692
+ # === @button_file_chooser
693
+ # ======================================================================= #
694
+ @button_pdf_viewer = button('Open in pdf viewer')
695
+ @button_pdf_viewer.hint =
696
+ 'Click this button to open the .pdf file in the pdf viewer.'
697
+ @button_pdf_viewer.clear_background
698
+ @button_pdf_viewer.skyblue
699
+ @button_pdf_viewer.bblack2
700
+ @button_pdf_viewer.on_clicked {
701
+ target_file = main_entry?.text?.to_s
702
+ if target_file and File.exist?(target_file)
703
+ do_determine_how_many_pages_are_in_the_pdf_file
704
+ system("evince #{target_file}")
705
+ else
706
+ bold_popover_message = bold_text(
707
+ 'Please assign an existing .pdf file in the top-left entry.'
708
+ )
709
+ bold_popover_message.set_font(default_font?)
710
+ popover_message(
711
+ bold_popover_message,
712
+ main_entry?
713
+ ).popup
714
+ end
715
+ }
716
+ end
717
+
718
+ # ========================================================================= #
719
+ # === run (run tag)
720
+ # ========================================================================= #
721
+ def run
722
+ run_super
723
+ end
724
+
725
+ # ========================================================================= #
726
+ # === PdfParadise::GUI::Gtk::DeleteTheFirstOrTheLastPageOfThisPdfFile.run
727
+ # ========================================================================= #
728
+ def self.run(
729
+ i = ARGV
730
+ )
731
+ require 'gtk_paradise/run'
732
+ _ = ::PdfParadise::GUI::Gtk::DeleteTheFirstOrTheLastPageOfThisPdfFile.new(i)
733
+ r = ::Gtk.run
734
+ r << _
735
+ r.automatic_size
736
+ r.automatic_title
737
+ r.top_left_then_run
738
+ end
739
+
740
+ # ========================================================================= #
741
+ # === PdfParadise::GUI::UniversalWidgets::DeleteTheFirstOrTheLastPageOfThisPdfFile[]
742
+ # ========================================================================= #
743
+ def self.[](i = ARGV)
744
+ new(i)
745
+ end
746
+
747
+ end; end; end
748
+
749
+ # =========================================================================== #
750
+ # === PdfParadise.return_widget_remove_first_page_of_pdf_file
751
+ # =========================================================================== #
752
+ def self.return_widget_remove_first_page_of_pdf_file
753
+ ::PdfParadise::GUI::Gtk::DeleteTheFirstOrTheLastPageOfThisPdfFile.new
754
+ end
755
+
756
+ # =========================================================================== #
757
+ # === PdfParadise.start_gtk_gui_remove_first_page_of_pdf_file
758
+ #
759
+ # This is a simple toplevel method that can be used to start the
760
+ # gtk3-GUI.
761
+ # =========================================================================== #
762
+ def self.start_gtk_gui_remove_first_page_of_pdf_file
763
+ require 'gtk_paradise/run'
764
+ _ = PdfParadise::GUI::Gtk::DeleteTheFirstOrTheLastPageOfThisPdfFile.new
765
+ r = ::Gtk.run
766
+ _.set_parent_widget(r)
767
+ r.easy_exit
768
+ r << _
769
+ r.top_left_then_run
770
+ end
771
+
772
+ end
773
+
774
+ if __FILE__ == $PROGRAM_NAME
775
+ PdfParadise::GUI::UniversalWidgets::DeleteTheFirstOrTheLastPageOfThisPdfFile.new(ARGV)
776
+ end # gtk_todo_viewer