File: reader.rb

package info (click to toggle)
omaque 1.0-1.1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 188 kB
  • ctags: 54
  • sloc: ruby: 456; sh: 5; makefile: 2
file content (347 lines) | stat: -rw-r--r-- 13,781 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
############################################################################
#    Copyright (C) 2008-2009 by David Palacio                              #
#    dpalacio@uninorte.edu.co                                              #
#                                                                          #
#    This program is free software; you can redistribute it and#or modify  #
#    it under the terms of the GNU General Public License as published by  #
#    the Free Software Foundation; either version 3 of the License, or     #
#    (at your option) any later version.                                   #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU General Public License for more details.                          #
#                                                                          #
#    You should have received a copy of the GNU General Public License     #
#    along with this program; if not, write to the                         #
#    Free Software Foundation, Inc.,                                       #
#    51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307, USA.          #
############################################################################

require 'okularpart'

module Reader
	class MainWindow < KDE::XmlGuiWindow
		
		KFILEDIALOG_DEFAULT_URL = 'kfiledialog:///omaque'
		
		slots :open_comic_book, 'open_comic_book(const KUrl&)', :open_next, :open_previous,
				:preferences, :apply_settings, :document_loaded,
				:toggle_full_screen, :toggle_show_menubar, :view_actual_size
		signals 'set_view_mode(QAction*)'
		
		def initialize
			super #nil,0 # para empanadear el constructor de KParts::MainWindow
			@part = OkularPart.create self
			@settings = {}
			@url = KDE::Url.new
			unless @part
				KDE::MessageBox.sorry nil, #make it global
				i18n("Could not find the Okular part.\nThe part is needed to display the comic books.\n\nPlease install Okular."),
				i18n('Could not find the Okular part')
				close
			else
				set_central_widget @part.widget
				setup_actions
				load_settings
			end
			#Without status bar for now. Looks empty and ugly
			setupGUI KDE::XmlGuiWindow::Default ^ KDE::XmlGuiWindow::StatusBar, 'mainwindow.rc'
			pageview = find_child( Qt::Object, 'okular::pageView')
			connect self, SIGNAL('set_view_mode(QAction*)'), pageview, SLOT('slotViewMode(QAction*)')
			connect @part, SIGNAL('completed()'), self, SLOT('document_loaded()')
		end
		
		def setup_actions
			#File menu
			KDE::StandardAction.open self, SLOT('open_comic_book()'), action_collection
			@recent_action = KDE::StandardAction.open_recent self, SLOT('open_comic_book(const KUrl&)'), action_collection
			@recent_action.load_entries( KDE::Global.config.group 'Recent Files' )
			next_action = KDE::Action.new self
			next_action.text = i18n 'Open Next'
			next_action.icon = KDE::Icon.new 'go-next'
			next_action.shortcut = KDE::Shortcut.new( 'CTRL+N; CTRL+Right' )
			connect next_action, SIGNAL('triggered()'), self, SLOT('open_next()')
			action_collection.add_action 'next', next_action
			previous_action = KDE::Action.new self
			previous_action.text = i18n 'Open Previous'
			previous_action.icon = KDE::Icon.new 'go-previous'
			previous_action.shortcut = KDE::Shortcut.new( 'CTRL+P; CTRL+Left' )
			connect previous_action, SIGNAL('triggered()'), self, SLOT('open_previous()')
			action_collection.add_action 'previous', previous_action
# 			KDE::StandardAction.close self, SLOT('close()'), action_collection
			KDE::StandardAction.quit $kapp, SLOT('quit()'), action_collection
			
			#View
			action_collection.add_action 'view_zoom_in',  @part.action_collection.action('view_zoom_in')
			action_collection.add_action 'view_zoom_out', @part.action_collection.action('view_zoom_out')
			action_collection.add_action 'view_fit_to_width', @part.action_collection.action('view_fit_to_width')
			action_collection.add_action 'view_fit_to_page', @part.action_collection.action('view_fit_to_page')
			action_collection.add_action 'view_continuous', @part.action_collection.action('view_continuous')
			action_collection.add_action 'view_render_mode', @part.action_collection.action('view_render_mode')
			action_collection.add_action 'view_orientation_rotate_ccw', @part.action_collection.action('view_orientation_rotate_ccw')
			action_collection.add_action 'view_orientation_rotate_cw', @part.action_collection.action('view_orientation_rotate_cw')
			action_collection.add_action 'view_orientation_original', @part.action_collection.action('view_orientation_original')

			action_collection.add_action 'go_previous', @part.action_collection.action('go_previous')
			action_collection.add_action 'go_next', @part.action_collection.action('go_next')
			action_collection.add_action 'first_page', @part.action_collection.action('first_page')
			action_collection.add_action 'last_page', @part.action_collection.action('last_page')
			action_collection.add_action 'go_document_back', @part.action_collection.action('go_document_back')
			action_collection.add_action 'go_document_forward', @part.action_collection.action('go_document_forward')
			action_collection.add_action 'go_goto_page', @part.action_collection.action('go_goto_page')
			
			#to save a qobject_cast, set it before before adding it to the collection
			@view_zoom_select = @part.action_collection.action('zoom_to')
			action_collection.add_action 'zoom_to', @view_zoom_select
			@actual_size_action = KDE::StandardAction.actual_size self, SLOT('view_actual_size()'), action_collection
			
			#Settings
			@show_menu_bar_action = KDE::StandardAction.show_menubar self, SLOT('toggle_show_menubar()'), action_collection
			@show_tool_bar_action = tool_bar_menu_action # FIXME: nil
			@full_screen_action = KDE::StandardAction.full_screen self, SLOT('toggle_full_screen()'), self, action_collection
			KDE::StandardAction.preferences self, SLOT('preferences()'), action_collection

			#Bookmarks
			dirs = KDE::StandardDirs.new
			data_path = dirs.save_location 'data', 'omaque'
			@bookmark_manager = KDE::BookmarkManager.manager_for_file data_path+'bookmarks.xml', 'omaque'
			@bookmark_owner = BookmarkOwner.new
			@bookmark_owner.source = self
			@bookmarks = KDE::ActionMenu.new i18n('Bookmarks'), self
			action_collection.add_action 'bookmarks', @bookmarks
			@bookmark_menu = KDE::BookmarkMenu.new @bookmark_manager, @bookmark_owner, @bookmarks.menu, action_collection
		end
		
		def open_comic_book( path = nil )
			unless path
				dialog = KDE::FileDialog.new KDE::Url.new(@settings[ :open_at ]), 'application/zip application/x-rar 
				application/x-cbz application/x-cbr', self
				dialog.mode = KDE::File::Directory|KDE::File::File
				dialog.exec
				path = dialog.selected_url
			else
				# We copy it because when it is emitted from KRecentFilesAction
				# it is semi-deleted on add_url
				path = KDE::Url.new path
			end
			return if path.empty?
			@part.closeUrl
			case (path.file_name)
			when /\.zip$/i
				cbz_arguments = KParts::OpenUrlArguments.new
				cbz_arguments.mime_type = 'application/x-cbz'
				@part.arguments = cbz_arguments
			when /\.rar$/i
				cbr_arguments = KParts::OpenUrlArguments.new
				cbr_arguments.mime_type = 'application/x-cbr'
				@part.arguments = cbr_arguments
			end
			begin
				@part.openUrl( path ) ? path : nil
			rescue NameError
				KDE::MessageBox.sorry nil,
						i18n('Do you have the Okular packages installed?'),
						i18n('An error ocurred')
			end
			view_mode = action_collection.action('view_render_mode').menu.
				actions.at(@settings[ :view_mode ].to_i)
			# most annoying Okular actions: view modes
			emit set_view_mode(view_mode)
			@url
		end

		def document_loaded
			@url = @part.url
			set_caption @url.file_name
			@recent_action.add_url( @url )
		end
		
		def local_open?
			@url && !@url.empty? && @url.isLocalFile # !! no funciona «local_file?»
		end
		
		def dir_entries( path, order )
			dir = Qt::Dir.new path
			( dir.entry_list [ '*.zip', '*.cbz', '*.rar', '*.cbr' ],
			Qt::Dir::Files | Qt::Dir::Readable,
			Qt::Dir::Name | Qt::Dir::IgnoreCase | order ) +
			( dir.entry_list Qt::Dir::Dirs | Qt::Dir::Readable,
			Qt::Dir::Name | Qt::Dir::IgnoreCase | order )
		end
		
		def get_next( path, entries, name )
			next_file = nil
			entries.inject do |previous, current|
				if previous == name
					next_file = current
					break
				end
				current
			end
			return KDE::Url.new unless next_file #ya estamos llamando open así que mejor enviemos un archivo inválido
			return KDE::Url.new( path + '/' + next_file )
		end
		
		def open_next( order = Qt::Dir::Name )
			return unless local_open?
			path = @url.up_url.path
			entries = dir_entries path, order
			open_comic_book get_next( path, entries, @url.file_name )
		end
		
		def open_previous
			open_next Qt::Dir::Reversed
		end
		
		def close_comic_book
			STDERR.puts 'close_comic_book: unsupported'
# 			Qt::MetaObject.invoke_method @part, 'closeUrl' #la parte dice que no se puede cerrar fuera de Okular o.O
		end
		
		def view_actual_size
			restore = @view_zoom_select.action '100%'
			@view_zoom_select.current_action = restore
			@view_zoom_select.action_triggered restore
		end
		
		def queryClose
			OkularPart.restore @part
			true
		end
		
		def queryExit
			OkularPart.restore @part
			save_settings
			config = KDE::Global.config
			@recent_action.save_entries config.group 'Recent Files' if @recent_action
			config.sync
			true
		end
		
		def load_settings
			config = KDE::Global.config
			settings = config.group 'Settings'
			@settings[ :open_at ] = settings.read_entry 'open_at', KFILEDIALOG_DEFAULT_URL
			@settings[ :view_mode ] = settings.read_entry 'view_mode', 0
			@settings[ :fit_mode ] = settings.read_entry 'fit_mode', 'view_fit_to_page'
			fit_action = action_collection.action @settings[ :fit_mode ].to_s
			(fit_action.checkable? ? fit_action.checked = true : fit_action.trigger) if fit_action
			@settings[ :continuous ] = settings.read_entry 'continuous', true
			action_collection.action('view_continuous').checked = @settings[ :continuous ]
		end
		
		def save_settings
			config = KDE::Global.config
			settings = config.group 'Settings'
			settings.write_entry 'open_at', @settings[ :open_at ]
			settings.write_entry 'view_mode', @settings[ :view_mode ]
			settings.write_entry 'fit_mode', @settings[ :fit_mode ]
			settings.write_entry 'continuous', @settings[ :continuous ]
		end
		
		def apply_settings
			config = KDE::Global.config
			@settings[ :open_at ] = @ui_settings.last_used.checked? ? KFILEDIALOG_DEFAULT_URL :
			@ui_settings.open_url.url.url
			@settings[ :fit_mode ] = @ui_settings.fit_combo.item_data(
				@ui_settings.fit_combo.current_index).to_string
			@settings[ :view_mode ] = @ui_settings.view_combo.item_data(
				@ui_settings.view_combo.current_index).to_int
			@settings[ :continuous ] = @ui_settings.continuous_check.checked?
			@preferences = nil
		end
		
		def toggle_show_menubar
			@show_menu_bar_action.checked? ?
				menu_bar.show :
				menu_bar.hide
		end
		
		#Based on the Okular Shell. License GPL2 or higher
		def toggle_full_screen
			if @full_screen_action.checked?
				#the toolbar action is not being created in the kxmlguiwindow. checking...
				@restore_from_fullscreen = { :menu_bar => @show_menu_bar_action.checked? }#, :tool_bar => @show_tool_bar_action.checked? }
				tool_bar.hide
				menu_bar.hide
				KDE::ToggleFullScreenAction.set_full_screen self, true
			else
				#always restore the toolbar for now
				tool_bar.show #if @restore_from_fullscreen[ :tool_bar ]
				menu_bar.show if @restore_from_fullscreen[ :menu_bar ]
				KDE::ToggleFullScreenAction.set_full_screen self, false
			end
		end
		
		def saveProperties( config_group )
			config_group.write_entry 'openFile', @url if @url
		end
		
		def readProperties( config_group )
			url = config_group.read_entry 'openFile', KDE::Url.new
			open_comic_book url
		end
		
		def preferences
			require 'ui_settings'
			unless @preferences
				@preferences = KDE::PageDialog.new self
				@ui_settings ||= Ui::Settings.new
				@ui_settings.setupUi(general = Qt::Widget.new)
				@preferences.add_page general, 'General'
				@ui_settings.open_url.file_dialog.mode = KDE::File::Directory
				@settings[ :open_at ] == KFILEDIALOG_DEFAULT_URL ?
					@ui_settings.last_used.checked = true :
					( @ui_settings.open_at.checked = true;
					  @ui_settings.open_url.url = KDE::Url.new @settings[ :open_at ] )
				fill_combo @ui_settings.fit_combo, @settings[ :fit_mode ],
						{ 'view_actual_size' => i18n('Actual size'),
				      'view_fit_to_width'=> i18n('Fit to width'),
				      'view_fit_to_page' => i18n('Fit to page') }
				fill_combo @ui_settings.view_combo, @settings[ :view_mode ],
						{ 0 => i18n('Single page'),
						  1 => i18n('Two pages') }
				@ui_settings.continuous_check.checked = @settings[ :continuous ]
				connect @preferences, SIGNAL('okClicked()'), self, SLOT('apply_settings()')
			end
			@preferences.show
		end
		
		def fill_combo( combobox, default, entries )
			entries.each_with_index do |pair, idx|
				combobox.add_item pair[1], Qt::Variant.new(pair[0])
				combobox.current_index = idx if pair[0] == default
			end
		end

		def url
			@url.url
		end

		def title
			@url.file_name
		end
		
	end
end

class BookmarkOwner < KDE::BookmarkOwner
	attr_accessor :source
	
	def openBookmark bookmark, buttons, modifiers
		@source.open_comic_book bookmark.url
	end

	def supportsTabs
		false
	end

	def currentTitle
		@source.title
	end

	def currentUrl
		@source.url
	end
end