lyrics-ebook 0.1

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 (106) hide show
  1. data/LICENSE +340 -0
  2. data/README +46 -0
  3. data/bin/lyrics-ebook +47 -0
  4. data/lib/eeepub/LICENSE +20 -0
  5. data/lib/eeepub/README.md +77 -0
  6. data/lib/eeepub/Rakefile +49 -0
  7. data/lib/eeepub/VERSION +1 -0
  8. data/lib/eeepub/examples/files/bar.html +42 -0
  9. data/lib/eeepub/examples/files/foo.html +42 -0
  10. data/lib/eeepub/examples/simple_epub.rb +25 -0
  11. data/lib/eeepub/lib/eeepub.rb +17 -0
  12. data/lib/eeepub/lib/eeepub/container_item.rb +108 -0
  13. data/lib/eeepub/lib/eeepub/easy.rb +100 -0
  14. data/lib/eeepub/lib/eeepub/maker.rb +127 -0
  15. data/lib/eeepub/lib/eeepub/ncx.rb +68 -0
  16. data/lib/eeepub/lib/eeepub/ocf.rb +112 -0
  17. data/lib/eeepub/lib/eeepub/opf.rb +148 -0
  18. data/lib/eeepub/spec/eeepub/easy_spec.rb +66 -0
  19. data/lib/eeepub/spec/eeepub/maker_spec.rb +124 -0
  20. data/lib/eeepub/spec/eeepub/ncx_spec.rb +80 -0
  21. data/lib/eeepub/spec/eeepub/ocf_spec.rb +43 -0
  22. data/lib/eeepub/spec/eeepub/opf_spec.rb +262 -0
  23. data/lib/eeepub/spec/eeepub_spec.rb +4 -0
  24. data/lib/eeepub/spec/spec_helper.rb +12 -0
  25. data/lib/lyrics_ebook.rb +71 -0
  26. data/lib/lyrics_ebook/cache2html.rb +33 -0
  27. data/lib/lyrics_ebook/cache_manager.rb +77 -0
  28. data/lib/lyrics_ebook/lyric.rb +32 -0
  29. data/lib/lyrics_ebook/lyric_download.rb +50 -0
  30. data/lib/lyrics_ebook/lyrics2html.rb +106 -0
  31. data/lib/lyrics_ebook/mini_lyrics_parser.rb +26 -0
  32. data/lib/lyrics_ebook/mp3_parser.rb +37 -0
  33. data/lib/wiki_lyrics/amarok/COPYING +340 -0
  34. data/lib/wiki_lyrics/amarok/README +51 -0
  35. data/lib/wiki_lyrics/amarok/amarok.rb +355 -0
  36. data/lib/wiki_lyrics/amarok/pluginadapter.rb +113 -0
  37. data/lib/wiki_lyrics/amarok/plugins.rb +95 -0
  38. data/lib/wiki_lyrics/amarok/wikilyrics.rb +578 -0
  39. data/lib/wiki_lyrics/amarok/wikilyrics.spec +4 -0
  40. data/lib/wiki_lyrics/amarok/wikipluginadapter.rb +392 -0
  41. data/lib/wiki_lyrics/cli/optionsparser.rb +228 -0
  42. data/lib/wiki_lyrics/cli/pluginadapter.rb +56 -0
  43. data/lib/wiki_lyrics/cli/plugins.rb +79 -0
  44. data/lib/wiki_lyrics/cli/wikilyrics.rb +178 -0
  45. data/lib/wiki_lyrics/cli/wikipluginadapter.rb +140 -0
  46. data/lib/wiki_lyrics/docs/COPYING +340 -0
  47. data/lib/wiki_lyrics/docs/ChangeLog +293 -0
  48. data/lib/wiki_lyrics/docs/HOWTO.pdf +0 -0
  49. data/lib/wiki_lyrics/docs/HOWTO.tex +151 -0
  50. data/lib/wiki_lyrics/docs/HOWTO.txt +139 -0
  51. data/lib/wiki_lyrics/docs/README +45 -0
  52. data/lib/wiki_lyrics/docs/TODO +12 -0
  53. data/lib/wiki_lyrics/gui/gui-gtk.rb +945 -0
  54. data/lib/wiki_lyrics/gui/gui-qt3.rb +785 -0
  55. data/lib/wiki_lyrics/gui/gui-qt4.rb +845 -0
  56. data/lib/wiki_lyrics/gui/gui-tk.rb +1104 -0
  57. data/lib/wiki_lyrics/gui/gui.rb +268 -0
  58. data/lib/wiki_lyrics/gui/test.rb +74 -0
  59. data/lib/wiki_lyrics/i18n/README +1 -0
  60. data/lib/wiki_lyrics/i18n/en.rb +181 -0
  61. data/lib/wiki_lyrics/i18n/es.rb +181 -0
  62. data/lib/wiki_lyrics/i18n/i18n.rb +126 -0
  63. data/lib/wiki_lyrics/i18n/sk.rb +174 -0
  64. data/lib/wiki_lyrics/itrans/COPYRIGHT +31 -0
  65. data/lib/wiki_lyrics/itrans/itrans +0 -0
  66. data/lib/wiki_lyrics/itrans/itrans.txt +8 -0
  67. data/lib/wiki_lyrics/itrans/lyric.txt +23 -0
  68. data/lib/wiki_lyrics/itrans/udvng.ifm +206 -0
  69. data/lib/wiki_lyrics/lyrics.rb +567 -0
  70. data/lib/wiki_lyrics/lyrics_AZLyrics.rb +113 -0
  71. data/lib/wiki_lyrics/lyrics_DarkLyrics.rb +124 -0
  72. data/lib/wiki_lyrics/lyrics_Giitaayan.rb +124 -0
  73. data/lib/wiki_lyrics/lyrics_Jamendo.rb +166 -0
  74. data/lib/wiki_lyrics/lyrics_LeosLyrics.rb +142 -0
  75. data/lib/wiki_lyrics/lyrics_LoudSongs.rb +135 -0
  76. data/lib/wiki_lyrics/lyrics_LyricWiki.rb +329 -0
  77. data/lib/wiki_lyrics/lyrics_LyricsDownload.rb +118 -0
  78. data/lib/wiki_lyrics/lyrics_LyricsMania.rb +141 -0
  79. data/lib/wiki_lyrics/lyrics_Lyriki.rb +287 -0
  80. data/lib/wiki_lyrics/lyrics_SeekLyrics.rb +108 -0
  81. data/lib/wiki_lyrics/lyrics_Sing365.rb +103 -0
  82. data/lib/wiki_lyrics/lyrics_TerraLetras.rb +126 -0
  83. data/lib/wiki_lyrics/mediawikilyrics.rb +1464 -0
  84. data/lib/wiki_lyrics/tests/plugin_tests.rb +161 -0
  85. data/lib/wiki_lyrics/tests/tests.rb +74 -0
  86. data/lib/wiki_lyrics/utils/formdata.rb +56 -0
  87. data/lib/wiki_lyrics/utils/htmlentities.rb +291 -0
  88. data/lib/wiki_lyrics/utils/http.rb +198 -0
  89. data/lib/wiki_lyrics/utils/itrans.rb +160 -0
  90. data/lib/wiki_lyrics/utils/kde.rb +88 -0
  91. data/lib/wiki_lyrics/utils/logger.rb +123 -0
  92. data/lib/wiki_lyrics/utils/strings.rb +378 -0
  93. data/lib/wiki_lyrics/utils/xmlhash.rb +111 -0
  94. data/lib/wiki_lyrics/wikilyrics.kdevelop +152 -0
  95. data/lib/wiki_lyrics/wikilyrics.kdevses +18 -0
  96. data/lib/wiki_lyrics/win/gtk_fix.bat +3 -0
  97. data/lib/wiki_lyrics/win/tk_fix.bat +3 -0
  98. data/lib/wiki_lyrics/win/wikilyrics.bat +4 -0
  99. data/lib/wiki_lyrics/win/win_fix.rb +52 -0
  100. data/templates/art_.erb.xhtml +29 -0
  101. data/templates/artists.erb.xhtml +19 -0
  102. data/templates/cover.erb.xhtml +22 -0
  103. data/test/cache_manager_test.rb +73 -0
  104. data/test/data/artist name/title name.lyric +6 -0
  105. data/test/lyric_test.rb +41 -0
  106. metadata +194 -0
@@ -0,0 +1,1104 @@
1
+ # Copyright (C) 2006-2008 by Sergio Pistone
2
+ # sergio_pistone@yahoo.com.ar
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the
16
+ # Free Software Foundation, Inc.,
17
+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
+
19
+ require "tk"
20
+ require "thread"
21
+ require "date"
22
+ require File.expand_path( File.dirname( __FILE__ ) + "/../i18n/i18n" )
23
+
24
+ module TK
25
+
26
+ def TK.empty_string?( text )
27
+ return text ? (text.empty? ? true : text.strip().empty?) : true
28
+ end
29
+
30
+ def TK.proc_args( args, defined=nil )
31
+ ret = {}
32
+ args.each() { |hash| hash.each() { |k,v| ret[k] = v } }
33
+ defined.each() { |k,v| ret[k] = v } if defined
34
+ return ret
35
+ end
36
+
37
+ class Label < TkLabel
38
+
39
+ def initialize( parent, text, *args )
40
+ super( parent, TK.proc_args( args, { "text"=> text } ) )
41
+ end
42
+
43
+ end
44
+
45
+ class Button < TkButton
46
+
47
+ def initialize( parent, text, *args )
48
+ super( parent, TK.proc_args( args, { "text"=> text } ) )
49
+ end
50
+
51
+ def set_enabled( enabled )
52
+ self.state = enabled ? "normal" : "disabled"
53
+ end
54
+
55
+ def is_enabled()
56
+ return state() != "disabled"
57
+ end
58
+
59
+ end
60
+
61
+ class TextArea < TkText
62
+
63
+ def initialize( parent, *args )
64
+ super( parent, TK.proc_args( args ) )
65
+ menu = TkMenu.new( self, "tearoff"=>false )
66
+ # menu.add( "command", "label"=>I18n.get( "gui.common.undo" ), "accel"=>"Ctrl+Z", "command"=>proc{undo()} )
67
+ # menu.add( "command", "label"=>I18n.get( "gui.common.redo" ), "accel"=>"Ctrl+Shift+Z", "command"=>proc{redo2()} )
68
+ # menu.add( "separator" )
69
+ menu.add( "command", "label"=>I18n.get( "gui.common.cut" ), "accel"=>"Ctrl+X", "command"=>proc { cut() } )
70
+ menu.add( "command", "label"=>I18n.get( "gui.common.copy" ), "accel"=>"Ctrl+C", "command"=>proc { copy() } )
71
+ menu.add( "command", "label"=>I18n.get( "gui.common.paste" ), "accel"=>"Ctrl+V", "command"=>proc { paste() } )
72
+ menu.add( "command", "label"=>I18n.get( "gui.common.delete" ), "accel"=>"Delete", "command"=>proc{delete_selection()} )
73
+ menu.add( "separator" )
74
+ menu.add( "command", "label"=>I18n.get( "gui.common.selectall" ), "accel"=>"Ctrl+A", "command"=>proc { select_all() } )
75
+ menu.bind( "FocusOut", proc { menu.unpost() } )
76
+
77
+ bind( "FocusOut", proc { select_none() } )
78
+ bind( "Button-3", proc { |e| menu.post( e.x_root, e.y_root ); menu.set_focus() } )
79
+ bind( "Control-Key-X", proc { cut(); Tk.callback_break() } )
80
+ bind( "Control-Key-x", proc { cut(); Tk.callback_break() } )
81
+ bind( "Control-Key-C", proc { copy(); Tk.callback_break() } )
82
+ bind( "Control-Key-c", proc { copy(); Tk.callback_break() } )
83
+ bind( "Control-Key-V", proc { paste(); Tk.callback_break() } )
84
+ bind( "Control-Key-v", proc { paste(); Tk.callback_break() } )
85
+ bind( "Control-Key-A", proc { select_all(); Tk.callback_break() } )
86
+ bind( "Control-Key-a", proc { select_all(); Tk.callback_break() } )
87
+ bind( "Control-Key-Z", proc { undo(); Tk.callback_break() } )
88
+ bind( "Control-Key-z", proc { undo(); Tk.callback_break() } )
89
+ bind( "Control-Shift-Key-Z", proc { redo2(); Tk.callback_break() } )
90
+ bind( "Control-Shift-Key-z", proc { redo2(); Tk.callback_break() } )
91
+ end
92
+
93
+ def select_all()
94
+ tag_add( "sel", "0.0", "end" )
95
+ end
96
+
97
+ def select_none()
98
+ tag_remove( "sel", "0.0", "end" )
99
+ end
100
+
101
+ def copy()
102
+ text_copy()
103
+ end
104
+
105
+ def cut()
106
+ text_cut()
107
+ end
108
+
109
+ def paste()
110
+ selected = tag_ranges( "sel" ).size > 0
111
+ if selected
112
+ length = value.size
113
+ tag_add( "prev_sel", "sel.first", "sel.last" )
114
+ end
115
+ text_paste()
116
+ delete( "prev_sel.first", "prev_sel.last" ) if selected && value.size != length
117
+ see( "insert" )
118
+ end
119
+
120
+ def delete_selection()
121
+ delete( "sel.first", "sel.last" ) if tag_ranges( "sel" ).size > 0
122
+ end
123
+
124
+ def undo()
125
+ end
126
+
127
+ def redo2()
128
+ end
129
+
130
+ def set_enabled( enabled )
131
+ self.state = enabled ? "normal" : "disabled"
132
+ end
133
+
134
+ def is_enabled()
135
+ return state() != "disabled"
136
+ end
137
+
138
+ def append_text( text )
139
+ insert( "end", text )
140
+ end
141
+
142
+ def get_value()
143
+ value()
144
+ end
145
+
146
+ def set_value( value )
147
+ delete( "0.0", "end" )
148
+ insert( "end", value )
149
+ end
150
+
151
+ alias value= set_value
152
+
153
+ alias get_text get_value
154
+ alias set_text set_value
155
+
156
+ alias text get_value
157
+ alias text= set_value
158
+
159
+ end
160
+
161
+ class SpinBox < TkSpinbox
162
+
163
+ def initialize( parent, value, *args )
164
+ @variable = TkVariable.new( value )
165
+ super( parent, TK.proc_args( args, { "textvariable"=> @variable } ) )
166
+ end
167
+
168
+ def set_enabled( enabled )
169
+ self.state = enabled ? "normal" : "disabled"
170
+ end
171
+
172
+ def is_enabled()
173
+ return state() != "disabled"
174
+ end
175
+
176
+ def get_value()
177
+ @variable.value()
178
+ end
179
+
180
+ def set_value( value )
181
+ @variable.set_value( value )
182
+ end
183
+
184
+ def get_min_value()
185
+ return self.from
186
+ end
187
+
188
+ def set_min_value( min_value )
189
+ self.from = min_value
190
+ end
191
+
192
+ def get_max_value()
193
+ return self.to
194
+ end
195
+
196
+ def set_max_value( max_value )
197
+ self.to = max_value
198
+ end
199
+
200
+ def set_range( min_value, max_value )
201
+ set_max_value( max_value )
202
+ set_min_value( min_value )
203
+ end
204
+
205
+ alias value get_value
206
+ alias value= set_value
207
+
208
+ alias min_value get_min_value
209
+ alias min_value= set_min_value
210
+
211
+ alias max_value get_max_value
212
+ alias max_value= set_max_value
213
+
214
+ end
215
+
216
+ class TextEdit < TkEntry
217
+
218
+ def initialize( parent, text, *args )
219
+ @variable = TkVariable.new( text )
220
+ super( parent, TK.proc_args( args, { "textvariable"=> @variable } ) )
221
+
222
+ menu = TkMenu.new( self, "tearoff"=>false )
223
+ # menu.add( "command", "label"=>I18n.get( "gui.common.undo" ), "accel"=>"Ctrl+Z", "command"=>proc { undo() } )
224
+ # menu.add( "command", "label"=>I18n.get( "gui.common.redo" ), "accel"=>"Ctrl+Shift+Z", "command"=>proc { redo2() } )
225
+ # menu.add( "separator" )
226
+ menu.add( "command", "label"=>I18n.get( "gui.common.cut" ), "accel"=>"Ctrl+X", "command"=>proc { cut() } )
227
+ menu.add( "command", "label"=>I18n.get( "gui.common.copy" ), "accel"=>"Ctrl+C", "command"=>proc { copy() } )
228
+ menu.add( "command", "label"=>I18n.get( "gui.common.paste" ), "accel"=>"Ctrl+V", "command"=>proc { paste() } )
229
+ menu.add( "command", "label"=>I18n.get( "gui.common.delete" ), "accel"=>"Delete", "command"=>proc{delete_selection()} )
230
+ menu.add( "separator" )
231
+ menu.add( "command", "label"=>I18n.get( "gui.common.selectall" ), "accel"=>"Ctrl+A", "command"=>proc { select_all() } )
232
+ menu.bind( "FocusOut", proc { menu.unpost() } )
233
+
234
+ bind( "Button-3", proc { |e| menu.post( e.x_root, e.y_root ); menu.set_focus() } )
235
+ bind( "FocusOut", proc { select_none() } )
236
+ bind( "Control-Key-X", proc { cut(); Tk.callback_break() } )
237
+ bind( "Control-Key-x", proc { cut(); Tk.callback_break() } )
238
+ bind( "Control-Key-C", proc { copy(); Tk.callback_break() } )
239
+ bind( "Control-Key-c", proc { copy(); Tk.callback_break() } )
240
+ bind( "Control-Key-V", proc { paste(); Tk.callback_break() } )
241
+ bind( "Control-Key-v", proc { paste(); Tk.callback_break() } )
242
+ bind( "Control-Key-A", proc { select_all(); Tk.callback_break() } )
243
+ bind( "Control-Key-a", proc { select_all(); Tk.callback_break() } )
244
+ bind( "Control-Key-Z", proc { undo(); Tk.callback_break() } )
245
+ bind( "Control-Key-z", proc { undo(); Tk.callback_break() } )
246
+ bind( "Control-Shift-Key-Z", proc { redo2(); Tk.callback_break() } )
247
+ bind( "Control-Shift-Key-z", proc { redo2(); Tk.callback_break() } )
248
+ end
249
+
250
+ def select_all()
251
+ selection_range( 0, "end" )
252
+ end
253
+
254
+ def select_none()
255
+ selection_clear()
256
+ end
257
+
258
+ def delete_selection()
259
+ delete( "sel.first", "sel.last" ) if selection_present()
260
+ end
261
+
262
+ def cut()
263
+ if selection_present()
264
+ TkClipboard.set( value().slice( index( "sel.first" ), index( "sel.last" ) ) )
265
+ delete( "sel.first", "sel.last" )
266
+ end
267
+ end
268
+
269
+ def copy()
270
+ TkClipboard.set( value().slice( index( "sel.first" ), index( "sel.last" ) ) ) if selection_present()
271
+ end
272
+
273
+ def paste()
274
+ data = TkClipboard.get()
275
+ if ! TK.empty_string?( data )
276
+ insert( index( "insert" ), data )
277
+ xview( "insert" )
278
+ delete( "sel.first", "sel.last" ) if selection_present()
279
+ end
280
+ end
281
+
282
+ def undo()
283
+ end
284
+
285
+ def redo2()
286
+ end
287
+
288
+ def set_enabled( enabled )
289
+ self.state = enabled ? "normal" : "disabled"
290
+ end
291
+
292
+ def is_enabled()
293
+ return state() != "disabled"
294
+ end
295
+
296
+ def get_value()
297
+ @variable.value()
298
+ end
299
+
300
+ def set_value( value )
301
+ @variable.set_value( value )
302
+ end
303
+
304
+ alias value get_value
305
+ alias value= set_value
306
+
307
+ alias get_text get_value
308
+ alias set_text set_value
309
+
310
+ alias text get_value
311
+ alias text= set_value
312
+
313
+ end
314
+
315
+ class CheckBox < TkCheckButton
316
+
317
+ def initialize( parent, text, *args )
318
+ super( parent, TK.proc_args( args, { "text"=> text } ) )
319
+ end
320
+
321
+ def set_enabled( enabled )
322
+ self.state = enabled ? "normal" : "disabled"
323
+ end
324
+
325
+ def is_enabled()
326
+ return state() != "disabled"
327
+ end
328
+
329
+ def get_value()
330
+ super() != "0"
331
+ end
332
+
333
+ alias value get_value
334
+ alias value= set_value
335
+
336
+ alias is_checked get_value
337
+ alias get_checked get_value
338
+ alias set_checked set_value
339
+
340
+ alias checked get_value
341
+ alias checked= set_value
342
+
343
+ end
344
+
345
+ class BaseDialog
346
+
347
+ attr_reader :accepted
348
+ attr_reader :values
349
+
350
+ def initialize( values, close_on_escape=true )
351
+ @root = TkRoot.new()
352
+ @root.withdraw()
353
+
354
+ @shell = TkToplevel.new( @root )
355
+ @shell.protocol( "WM_DELETE_WINDOW", proc { destroy() } )
356
+ @shell.bind( "Escape", proc { destroy() } ) if close_on_escape
357
+ @shell.withdraw() # hide the window until everything is created
358
+
359
+ @values = values
360
+ @x, @y, @width, @height = nil, nil, nil, nil
361
+ end
362
+
363
+ def exec()
364
+
365
+ @accepted = false
366
+
367
+ # center the dialog:
368
+ if ! @x && ! @y
369
+ set_size( @width, @height ) if @width
370
+ width, height = get_size()
371
+ s_width, s_height = BaseDialog.get_screen_size()
372
+ @x, @y = (s_width - width) / 2, (s_height - height) / 2
373
+ end
374
+ set_position( @x, @y )
375
+
376
+ @shell.deiconify() # the windows is hidden initially so we have to show it
377
+
378
+ Tk.mainloop()
379
+ Tk.restart()
380
+ end
381
+
382
+ def destroy()
383
+ @root.destroy()
384
+ end
385
+
386
+ def accept()
387
+ @accepted = true
388
+ destroy()
389
+ end
390
+
391
+ def set_size( width, height )
392
+ @width, @height = width.to_i(), height.to_i()
393
+ @shell.geometry( "#{@width}x#{@height}" ) if @shell
394
+ end
395
+
396
+ def set_position( x, y )
397
+ @x, @y = x.to_i(), y.to_i()
398
+ @shell.geometry( "#{@x > 0 ? "+" : "-"}#{@x}#{@y > 0 ? "+" : "-"}#{@y}" ) if @shell
399
+ end
400
+
401
+ def get_size()
402
+ return @width.to_i(), @height.to_i() if @width
403
+ width, height = nil, nil
404
+ if @shell
405
+ md = /([0-9]+)x([0-9]+)[-\+][0-9]+[-\+][0-9]+/.match( @shell.geometry() )
406
+ width, height = md[1].to_i(), md[2].to_i()
407
+ end
408
+ return width, height
409
+ end
410
+
411
+ def get_position()
412
+ return @x.to_i(), @y.to_i()
413
+ end
414
+
415
+ def BaseDialog.get_screen_size()
416
+ maxsize = Tk.root.maxsize()
417
+ return maxsize[0], maxsize[1]
418
+ end
419
+
420
+ def create_action_buttons( mode="right", accept_text=nil, cancel_text=nil )
421
+ parent = self
422
+ buttons_frame = TkFrame.new( @shell )
423
+ accept_text = TK.empty_string?( accept_text ) ? I18n.get( "gui.common.accept" ) : accept_text
424
+ cancel_text = TK.empty_string?( cancel_text ) ? I18n.get( "gui.common.cancel" ) : cancel_text
425
+ @accept_button = Button.new( buttons_frame, accept_text ) { command { parent.accept() } }
426
+ @cancel_button = Button.new( buttons_frame, cancel_text ) { command { parent.destroy() } }
427
+ if mode == "left"
428
+ @accept_button.pack( "side"=>"left" )
429
+ @cancel_button.pack( "side"=>"left" )
430
+ elsif mode == "split"
431
+ @accept_button.pack( "side"=>"left", "fill"=>"x", "expand"=>"true" )
432
+ @cancel_button.pack( "side"=>"right", "fill"=>"x", "expand"=>"true" )
433
+ else
434
+ @cancel_button.pack( "side"=>"right" )
435
+ @accept_button.pack( "side"=>"right" )
436
+ end
437
+ return buttons_frame
438
+ end
439
+ protected :create_action_buttons
440
+
441
+ end
442
+
443
+ class PluginsManagerDialog < BaseDialog
444
+
445
+ def initialize( values )
446
+ super( values )
447
+
448
+ set_size( 400, 230 )
449
+
450
+ @shell.title( I18n.get( "gui.pluginsmanager.title", @values["script_name"] ) )
451
+
452
+ label = Label.new( @shell, I18n.get( "gui.pluginsmanager.sites" ) )
453
+ label.grid( "row"=>1, "column"=>1, "columnspan"=>4, "sticky"=>"w" )
454
+
455
+ frame = TkFrame.new( @shell )
456
+ frame.grid( "row"=>2, "rowspan"=>4, "column"=>2, "sticky"=>"nesw" )
457
+ @used_plugins_list = TkListbox.new( frame, "selectmode" => "single" )
458
+ @values["used_plugins"].each() { |plugin| @used_plugins_list.insert( "end", plugin ) }
459
+ @used_plugins_list.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
460
+ y_scroll_bar = TkScrollbar.new( frame, "orient"=>"ver" )
461
+ y_scroll_bar.command( proc { |*args| @used_plugins_list.yview( *args ) } )
462
+ y_scroll_bar.pack( "side"=>"right", "fill"=>"y" )
463
+ @used_plugins_list.yscrollcommand( proc { |first, last| y_scroll_bar.set( first, last ) } )
464
+
465
+ frame = TkFrame.new( @shell )
466
+ frame.grid( "row"=>2, "rowspan"=>4, "column"=>4, "sticky"=>"nesw" )
467
+ @unused_plugins_list = TkListbox.new( frame, "selectmode" => "single" )
468
+ @values["unused_plugins"].each() { |plugin| @unused_plugins_list.insert( "end", plugin ) }
469
+ @unused_plugins_list.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
470
+ y_scroll_bar = TkScrollbar.new( frame, "orient"=>"ver" )
471
+ y_scroll_bar.command( proc { |*args| @unused_plugins_list.yview( *args ) } )
472
+ y_scroll_bar.pack( "side"=>"right", "fill"=>"y" )
473
+ @unused_plugins_list.yscrollcommand( proc { |first, last| y_scroll_bar.set( first, last ) } )
474
+
475
+ @move_up_button = Button.new( @shell, I18n.get( "gui.pluginsmanager.sites.moveup" ) )
476
+ @move_up_button.command( proc { move_up() } )
477
+ @move_up_button.grid( "row"=>3, "column"=>1, "sticky"=>"ew" )
478
+
479
+ @move_down_button = Button.new( @shell, I18n.get( "gui.pluginsmanager.sites.movedown" ) )
480
+ @move_down_button.command( proc { move_down() } )
481
+ @move_down_button.grid( "row"=>4, "column"=>1, "sticky"=>"ew" )
482
+
483
+ @add_button = Button.new( @shell, I18n.get( "gui.pluginsmanager.sites.add" ) )
484
+ @add_button.command( proc { add_plugin() } )
485
+ @add_button.grid( "row"=>3, "column"=>3, "sticky"=>"ew" )
486
+
487
+ @remove_button = Button.new( @shell, I18n.get( "gui.pluginsmanager.sites.remove" ) )
488
+ @remove_button.command( proc { remove_plugin() } )
489
+ @remove_button.grid( "row"=>4, "column"=>3, "sticky"=>"ew" )
490
+
491
+ @cleanup_lyrics_checkbox = CheckBox.new( @shell, I18n.get( "gui.pluginsmanager.misc.cleanup" ) )
492
+ @cleanup_lyrics_checkbox.set_checked( @values["cleanup_lyrics"].to_s() == "true" )
493
+ @cleanup_lyrics_checkbox.grid( "row"=>6, "column"=>1, "columnspan"=>4, "sticky"=>"w" )
494
+
495
+ @single_threaded_checkbox = CheckBox.new( @shell, I18n.get( "gui.pluginsmanager.misc.singlethreaded" ) )
496
+ @single_threaded_checkbox.set_checked( @values["single_threaded"].to_s() == "true" )
497
+ @single_threaded_checkbox.grid( "row"=>7, "column"=>1, "columnspan"=>4, "sticky"=>"w" )
498
+
499
+ @write_log_checkbox = CheckBox.new( @shell, I18n.get( "gui.pluginsmanager.misc.writelog", "$HOME/.wikilyrics.log" ) )
500
+ @write_log_checkbox.set_checked( @values["write_log"].to_s() == "true" )
501
+ @write_log_checkbox.grid( "row"=>8, "column"=>1, "columnspan"=>4, "sticky"=>"w" )
502
+
503
+ buttons = create_action_buttons()
504
+ buttons.grid( "row"=>9, "column"=>1, "columnspan"=>4, "sticky"=>"ew" )
505
+
506
+ update_accept_button()
507
+
508
+ @shell.grid_rowconfigure( 2, "weight"=>1 )
509
+ @shell.grid_rowconfigure( 5, "weight"=>1 )
510
+ @shell.grid_columnconfigure( 2, "weight"=>1 )
511
+ @shell.grid_columnconfigure( 4, "weight"=>1 )
512
+ end
513
+
514
+ def get_active_index( list_box )
515
+ list_box.size.times do |idx|
516
+ return idx if list_box.selection_includes( idx )
517
+ end
518
+ return nil
519
+ end
520
+
521
+ def move_up()
522
+ active_idx = get_active_index( @used_plugins_list )
523
+ return if active_idx == nil || active_idx == 0
524
+ active = @used_plugins_list.get( active_idx )
525
+ @used_plugins_list.delete( active_idx )
526
+ @used_plugins_list.insert( active_idx-1, active )
527
+ @used_plugins_list.selection_set( active_idx-1 )
528
+ end
529
+
530
+ def move_down()
531
+ active_idx = get_active_index( @used_plugins_list )
532
+ return if active_idx == nil || active_idx == @used_plugins_list.size - 1
533
+ active = @used_plugins_list.get( active_idx )
534
+ @used_plugins_list.delete( active_idx )
535
+ @used_plugins_list.insert( active_idx+1, active )
536
+ @used_plugins_list.selection_set( active_idx+1 )
537
+ end
538
+
539
+ def add_plugin()
540
+ active_idx = get_active_index( @unused_plugins_list )
541
+ return if active_idx == nil
542
+ active = @unused_plugins_list.get( active_idx )
543
+ @unused_plugins_list.delete( active_idx )
544
+ @used_plugins_list.insert( "end", active )
545
+ @used_plugins_list.selection_set( "end" )
546
+ update_accept_button()
547
+ end
548
+
549
+ def remove_plugin()
550
+ active_idx = get_active_index( @used_plugins_list )
551
+ return if active_idx == nil
552
+ active = @used_plugins_list.get( active_idx )
553
+ @used_plugins_list.delete( active_idx )
554
+ @unused_plugins_list.insert( "end", active )
555
+ @unused_plugins_list.selection_set( "end" )
556
+ update_accept_button()
557
+ end
558
+
559
+ def update_accept_button()
560
+ @accept_button.state = @used_plugins_list.size > 0 ? "normal" : "disabled"
561
+ end
562
+
563
+ def accept()
564
+ @values = {
565
+ "cleanup_lyrics" => @cleanup_lyrics_checkbox.is_checked(),
566
+ "single_threaded" => @single_threaded_checkbox.is_checked(),
567
+ "write_log" => @write_log_checkbox.is_checked(),
568
+ "script_name" => @values["script_name"],
569
+ "used_plugins" => [],
570
+ "unused_plugins" => []
571
+ }
572
+ @used_plugins_list.size.times do |idx|
573
+ @values["used_plugins"].insert( -1, @used_plugins_list.get( idx ) )
574
+ end
575
+ @unused_plugins_list.size.times do |idx|
576
+ @values["unused_plugins"].insert( -1, @unused_plugins_list.get( idx ) )
577
+ end
578
+ super()
579
+ end
580
+
581
+ end
582
+
583
+
584
+ class WikiPluginDialog < BaseDialog
585
+
586
+ def initialize( values )
587
+ super( values )
588
+
589
+ set_size( 360, 210 )
590
+
591
+ @shell.title( I18n.get( "gui.wikiplugin.title", values["site_name"] ) )
592
+
593
+ label = Label.new( @shell, I18n.get( "gui.wikiplugin.general" ) )
594
+ label.grid( "row"=>1, "column"=>1, "columnspan"=>4, "sticky"=>"w" )
595
+
596
+ @submit_checkbox = CheckBox.new( @shell, I18n.get( "gui.wikiplugin.general.submit", values["site_name"] ) )
597
+ @submit_checkbox.set_checked( values["submit"].to_s() == "true" )
598
+ @submit_checkbox.command( proc { toggle_submit_checked() } )
599
+ @submit_checkbox.grid( "row"=>2, "column"=>1, "columnspan"=>3, "sticky"=>"w" )
600
+
601
+ @review_checkbox = CheckBox.new( @shell, I18n.get( "gui.wikiplugin.general.review" ) )
602
+ @review_checkbox.command( proc { toggle_review_checked() } )
603
+ @review_checkbox.set_enabled( @submit_checkbox.is_checked() )
604
+ @review_checkbox.set_checked( @review_checkbox.is_enabled() && values["review"].to_s() == "true" )
605
+ @review_checkbox.grid( "row"=>3, "column"=>1, "columnspan"=>3, "sticky"=>"w" )
606
+
607
+ @prompt_autogen_checkbox = CheckBox.new( @shell, I18n.get( "gui.wikiplugin.general.autogen" ) )
608
+ @prompt_autogen_checkbox.set_enabled( @review_checkbox.is_checked() )
609
+ @prompt_autogen_checkbox.set_checked( @prompt_autogen_checkbox.is_enabled() && values["prompt_autogen"].to_s() == "true" )
610
+ @prompt_autogen_checkbox.grid( "row"=>4, "column"=>1, "columnspan"=>3, "sticky"=>"w" )
611
+
612
+ @prompt_no_lyrics_checkbox = CheckBox.new( @shell, I18n.get( "gui.wikiplugin.general.nolyrics" ) )
613
+ @prompt_no_lyrics_checkbox.set_enabled( @review_checkbox.is_checked() )
614
+ @prompt_no_lyrics_checkbox.set_checked( @prompt_no_lyrics_checkbox.is_enabled() && values["prompt_no_lyrics"].to_s() == "true" )
615
+ @prompt_no_lyrics_checkbox.grid( "row"=>5, "column"=>1, "columnspan"=>3, "sticky"=>"w" )
616
+
617
+ label = Label.new( @shell, I18n.get( "gui.wikiplugin.login" ) )
618
+ label.grid( "row"=>7, "column"=>1, "columnspan"=>4, "sticky"=>"w" )
619
+
620
+ label = Label.new( @shell, I18n.get( "gui.wikiplugin.login.username" ) )
621
+ label.grid( "row"=>8, "column"=>1 )
622
+ @username_lineedit = TextEdit.new( @shell, values["username"] )
623
+ @username_lineedit.grid( "row"=>8, "column"=>2, "columnspan"=>2, "sticky"=>"ew" )
624
+
625
+ label = Label.new( @shell, I18n.get( "gui.wikiplugin.login.password" ) )
626
+ label.grid( "row"=>9, "column"=>1 )
627
+ @password_lineedit = TextEdit.new( @shell, values["password"], "show"=>"*" )
628
+ @password_lineedit.grid( "row"=>9, "column"=>2, "columnspan"=>2, "sticky"=>"ew" )
629
+
630
+ @username_lineedit.bind( "KeyRelease", proc { update_accept_button_state() } )
631
+
632
+ buttons = create_action_buttons()
633
+ buttons.grid( "row"=>11, "column"=>1, "columnspan"=>4, "sticky"=>"ew" )
634
+ update_accept_button_state()
635
+
636
+ @shell.grid_rowconfigure( 6, "weight"=>1 )
637
+ @shell.grid_rowconfigure( 10, "weight"=>5 )
638
+ @shell.grid_columnconfigure( 2, "weight"=>1 )
639
+ @shell.grid_columnconfigure( 3, "weight"=>1 )
640
+ end
641
+
642
+ def toggle_submit_checked()
643
+ @review_checkbox.set_enabled( @submit_checkbox.is_checked() )
644
+ if ! @review_checkbox.is_enabled()
645
+ @review_checkbox.set_checked( false )
646
+ @prompt_autogen_checkbox.set_checked( false )
647
+ @prompt_no_lyrics_checkbox.set_checked( false )
648
+ @prompt_autogen_checkbox.set_enabled( false )
649
+ @prompt_no_lyrics_checkbox.set_enabled( false )
650
+ end
651
+ update_accept_button_state()
652
+ end
653
+
654
+ def toggle_review_checked()
655
+ enabled = @review_checkbox.is_checked()
656
+ @prompt_autogen_checkbox.set_enabled( enabled )
657
+ @prompt_no_lyrics_checkbox.set_enabled( enabled )
658
+ if ! enabled
659
+ @prompt_autogen_checkbox.set_checked( false )
660
+ @prompt_no_lyrics_checkbox.set_checked( false )
661
+ end
662
+ end
663
+
664
+ def update_accept_button_state()
665
+ @accept_button.set_enabled( ! @submit_checkbox.is_checked() || ! @username_lineedit.text().empty? )
666
+ end
667
+
668
+ def accept()
669
+ @values = {
670
+ "submit" => @submit_checkbox.is_checked(),
671
+ "review" => @review_checkbox.is_checked(),
672
+ "prompt_autogen" => @prompt_autogen_checkbox.is_checked(),
673
+ "prompt_no_lyrics" => @prompt_no_lyrics_checkbox.is_checked(),
674
+ "username" => @username_lineedit.text(),
675
+ "password" => @password_lineedit.text(),
676
+ }
677
+ super()
678
+ end
679
+
680
+ end
681
+
682
+ class SubmitSongDialog < BaseDialog
683
+
684
+ def initialize( values )
685
+ super( values )
686
+
687
+ set_size( 600, 400 )
688
+
689
+ edit_mode = @values["edit_mode"].to_s() == "true"
690
+ @shell.title( I18n.get( "gui.submitsong.title." + (edit_mode ? "edit" : "submit"), values["site_name"] ) )
691
+
692
+ artist_label = Label.new( @shell, I18n.get( "gui.common.artist" ) )
693
+ artist_label.grid( "row"=>1, "column"=>1, "sticky"=>"ew" )
694
+ @artist_lineedit = TextEdit.new( @shell, values["artist"] )
695
+ @artist_lineedit.grid( "row"=>1, "column"=>2, "sticky"=>"ew" )
696
+
697
+ title_label = Label.new( @shell, I18n.get( "gui.common.song" ) )
698
+ title_label.grid( "row"=>1, "column"=>3, "sticky"=>"ew" )
699
+ @title_lineedit = TextEdit.new( @shell, values["title"] )
700
+ @title_lineedit.grid( "row"=>1, "column"=>4, "sticky"=>"ew" )
701
+
702
+ credits_label = Label.new( @shell, I18n.get( "gui.common.credits" ) )
703
+ credits_label.grid( "row"=>2, "column"=>1, "sticky"=>"ew" )
704
+ @credits_lineedit = TextEdit.new( @shell, values["credits"] )
705
+ @credits_lineedit.grid( "row"=>2, "column"=>2, "sticky"=>"ew" )
706
+
707
+ lyricist_label = Label.new( @shell, I18n.get( "gui.common.lyricist" ) )
708
+ lyricist_label.grid( "row"=>2, "column"=>3, "sticky"=>"ew" )
709
+ @lyricist_lineedit = TextEdit.new( @shell, values["lyricist"] )
710
+ @lyricist_lineedit.grid( "row"=>2, "column"=>4, "sticky"=>"ew" )
711
+
712
+ year_label = Label.new( @shell, I18n.get( "gui.common.year" ) )
713
+ year_label.grid( "row"=>3, "column"=>1, "sticky"=>"ew" )
714
+ @year_spinbox = SpinBox.new( @shell, values["year"] )
715
+ @year_spinbox.set_range( 1900, Date.today().year )
716
+ @year_spinbox.grid( "row"=>3, "column"=>2, "sticky"=>"ew" )
717
+
718
+ album_label = Label.new( @shell, I18n.get( "gui.common.album" ) )
719
+ album_label.grid( "row"=>3, "column"=>3, "sticky"=>"ew" )
720
+ @album_lineedit = TextEdit.new( @shell, values["album"] )
721
+ @album_lineedit.grid( "row"=>3, "column"=>4, "sticky"=>"ew" )
722
+
723
+ @instrumental_checkbox = CheckBox.new( @shell, I18n.get( "gui.submitsong.instrumental" ) )
724
+ @instrumental_checkbox.set_checked( values["instrumental"].to_s() == "true" )
725
+ @instrumental_checkbox.command = proc { toggle_instrumental_checked() }
726
+ @instrumental_checkbox.grid( "row"=>4, "column"=>1, "columnspan"=>3, "sticky"=>"w" )
727
+
728
+ lyrics_frame = TkFrame.new( @shell )
729
+ lyrics_frame.grid( "row"=>5, "column"=>1, "columnspan"=>4, "sticky"=>"nesw" )
730
+ bar = TkScrollbar.new( lyrics_frame, "orient"=>"ver" )
731
+ bar.pack( "side"=>"right", "fill"=>"y" )
732
+ @lyrics_text = TextArea.new( lyrics_frame ) { yscrollcommand { |first, last| bar.set( first, last ) } }
733
+ @lyrics_text.set_text( values["lyrics"] )
734
+ @lyrics_text.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
735
+ bar.command( proc { |*args| @lyrics_text.yview( *args ) } )
736
+ toggle_instrumental_checked()
737
+
738
+ @reviewed_checkbox = CheckBox.new( @shell, I18n.get( "gui.common.reviewed" ) )
739
+ @reviewed_checkbox.set_checked( false )
740
+ @reviewed_checkbox.grid( "row"=>6, "column"=>1, "columnspan"=>4, "sticky"=>"w" )
741
+
742
+ buttons = create_action_buttons( "split", I18n.get( "gui.common.submit" ) )
743
+ buttons.grid( "row"=>7, "column"=>1, "columnspan"=>4, "sticky"=>"ew" )
744
+
745
+ @shell.grid_rowconfigure( 5, "weight"=>1 )
746
+ 4.times { |idx| @shell.grid_columnconfigure( idx+1, "weight"=>1 ) }
747
+ end
748
+
749
+ def toggle_instrumental_checked()
750
+ @lyrics_text.set_enabled( ! @instrumental_checkbox.is_checked() )
751
+ end
752
+
753
+ def accept()
754
+ @values = {
755
+ "artist" => @artist_lineedit.text(),
756
+ "year" => @year_spinbox.value(),
757
+ "album" => @album_lineedit.text(),
758
+ "title" => @title_lineedit.text(),
759
+ "lyrics" => @lyrics_text.text(),
760
+ "instrumental" => @instrumental_checkbox.is_checked(),
761
+ "lyricist" => @lyricist_lineedit.text(),
762
+ "credits" => @credits_lineedit.text(),
763
+ "reviewed" => @reviewed_checkbox.is_checked()
764
+ }
765
+ super()
766
+ end
767
+
768
+ end
769
+
770
+
771
+ class SubmitAlbumDialog < BaseDialog
772
+
773
+ def initialize( values )
774
+ super( values )
775
+
776
+ set_size( 600, 400 )
777
+
778
+ @shell.title( I18n.get( "gui.submitalbum.title", values["site_name"] ) )
779
+
780
+ artist_label = Label.new( @shell, I18n.get( "gui.common.artist" ) )
781
+ artist_label.grid( "row"=>1, "column"=>1, "sticky"=>"ew" )
782
+ @artist_lineedit = TextEdit.new( @shell, values["artist"] )
783
+ @artist_lineedit.grid( "row"=>1, "column"=>2, "columnspan"=>5, "sticky"=>"ew" )
784
+
785
+ album_label = Label.new( @shell, I18n.get( "gui.common.album" ) )
786
+ album_label.grid( "row"=>2, "column"=>1, "sticky"=>"ew" )
787
+ @album_lineedit = TextEdit.new( @shell, values["album"] )
788
+ @album_lineedit.grid( "row"=>2, "column"=>2, "columnspan"=>5, "sticky"=>"ew" )
789
+
790
+ label = Label.new( @shell, I18n.get( "gui.common.year" ) )
791
+ label.grid( "row"=>3, "column"=>1, "sticky"=>"ew" )
792
+ @year_spinbox = SpinBox.new( @shell, values["year"].to_i() )
793
+ @year_spinbox.set_range( 1900, Date.today().year )
794
+ @year_spinbox.grid( "row"=>3, "column"=>2, "sticky"=>"ew" )
795
+
796
+ label = Label.new( @shell, I18n.get( "gui.common.month" ) )
797
+ label.grid( "row"=>3, "column"=>3, "sticky"=>"ew" )
798
+ @month_spinbox = SpinBox.new( @shell, values["month"].to_i() )
799
+ @month_spinbox.set_range( 0, 12 )
800
+ @month_spinbox.grid( "row"=>3, "column"=>4, "sticky"=>"ew" )
801
+
802
+ label = Label.new( @shell, I18n.get( "gui.common.day" ) )
803
+ label.grid( "row"=>3, "column"=>5, "sticky"=>"ew" )
804
+ @day_spinbox = SpinBox.new( @shell, values["day"].to_i() )
805
+ @day_spinbox.set_range( 0, 31 )
806
+ @day_spinbox.grid( "row"=>3, "column"=>6, "sticky"=>"ew" )
807
+
808
+ image_label = Label.new( @shell, I18n.get( "gui.common.image" ) )
809
+ image_label.grid( "row"=>4, "column"=>1, "sticky"=>"ew" )
810
+
811
+ image_frame = TkFrame.new( @shell )
812
+ image_frame.grid( "row"=>4, "column"=>2, "columnspan"=>5, "sticky"=>"ew" )
813
+
814
+ @image_path_lineedit = TextEdit.new( image_frame, @values.include?( "image_path" ) ? @values["image_path"] : I18n.get( "gui.submitalbum.coverfound" ) )
815
+ @image_path_lineedit.set_enabled( @values.include?( "image_path" ) )
816
+ @image_path_lineedit.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
817
+
818
+ if values.include?( "image_path" )
819
+ @image_button = Button.new( image_frame, "..." )
820
+ @image_button.command( proc { browse_image() } )
821
+ @image_button.pack( "side"=>"right" )
822
+ end
823
+
824
+ tracks_frame = TkFrame.new( @shell )
825
+ tracks_frame.grid( "row"=>5, "column"=>1, "columnspan"=>6, "sticky"=>"nesw" )
826
+ bar = TkScrollbar.new( tracks_frame, "orient"=>"ver" )
827
+ bar.pack( "side"=>"right", "fill"=>"y" )
828
+ @tracks_text = TextArea.new( tracks_frame ) { yscrollcommand { |first, last| bar.set( first, last ) } }
829
+ @tracks_text.set_text( values["tracks"] )
830
+ @tracks_text.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
831
+ bar.command( proc { |*args| @tracks_text.yview( *args ) } )
832
+
833
+ @reviewed_checkbox = CheckBox.new( @shell, I18n.get( "gui.common.reviewed" ) )
834
+ @reviewed_checkbox.set_checked( false )
835
+ @reviewed_checkbox.grid( "row"=>6, "column"=>1, "columnspan"=>6, "sticky"=>"w" );
836
+
837
+ buttons = create_action_buttons( "split", I18n.get( "gui.common.submit" ) )
838
+ buttons.grid( "row"=>7, "column"=>1, "columnspan"=>6, "sticky"=>"ew" )
839
+
840
+ @shell.grid_rowconfigure( 5, "weight"=>1 )
841
+ 6.times { |idx| @shell.grid_columnconfigure( idx+1, "weight"=>1 ) }
842
+ end
843
+
844
+ def browse_image()
845
+ dirname = @image_path_lineedit.text().strip()
846
+ dirname = TK.empty_string?( dirname ) ? (ENV["HOME"] ? ENV["HOME"] : ".") : File.dirname( dirname )
847
+ image_path = Tk.getOpenFile( {
848
+ "parent" => @shell,
849
+ "title" => I18n.get( "gui.uploadcover.browseimage.title" ),
850
+ "initialdir" => dirname,
851
+ "filetypes" => [
852
+ [I18n.get( "gui.uploadcover.browseimage.images" ), ".jpg .JPG .png .PNG .bmp .BMP"],
853
+ [I18n.get( "gui.uploadcover.browseimage.allfiles" ), "*"]
854
+ ]
855
+ } )
856
+ @image_path_lineedit.set_value( image_path.strip() ) if ! TK.empty_string?( image_path )
857
+ end
858
+
859
+ def accept()
860
+ aux = {
861
+ "artist" => @artist_lineedit.text(),
862
+ "album" => @album_lineedit.text(),
863
+ "year" => @year_spinbox.value(),
864
+ "month" => @month_spinbox.value(),
865
+ "day" => @day_spinbox.value(),
866
+ "tracks" => @tracks_text.text(),
867
+ "reviewed" => @reviewed_checkbox.is_checked()
868
+ }
869
+ aux["image_path"] = @image_path_lineedit.text() if @values.include?( "image_path" )
870
+ @values = aux
871
+ super()
872
+ end
873
+
874
+ end
875
+
876
+
877
+ class UploadCoverDialog < BaseDialog
878
+
879
+ def initialize( values )
880
+ super( values )
881
+
882
+ set_size( 380, 180 )
883
+
884
+ @shell.title( I18n.get( "gui.uploadcover.title", values["site_name"] ) )
885
+
886
+ label = Label.new( @shell, I18n.get( "gui.common.album" ) )
887
+ label.grid( "row"=>1, "column"=>1, "sticky"=>"w" )
888
+
889
+ label = Label.new( @shell, I18n.get( "gui.common.artist" ) )
890
+ label.grid( "row"=>2, "column"=>1 )
891
+ @artist_lineedit = TextEdit.new( @shell, @values["artist"] )
892
+ @artist_lineedit.grid( "row"=>2, "column"=>2, "sticky"=>"ew" )
893
+
894
+ label = Label.new( @shell, I18n.get( "gui.common.album" ) )
895
+ label.grid( "row"=>3, "column"=>1 )
896
+ @album_lineedit = TextEdit.new( @shell, @values["album"] )
897
+ @album_lineedit.grid( "row"=>3, "column"=>2, "sticky"=>"ew" )
898
+
899
+ label = Label.new( @shell, I18n.get( "gui.common.year" ) )
900
+ label.grid( "row"=>4, "column"=>1 )
901
+ @year_spinbox = SpinBox.new( @shell, values["year"] )
902
+ @year_spinbox.set_range( 1900, Date.today().year )
903
+ @year_spinbox.grid( "row"=>4, "column"=>2, "sticky"=>"ew" )
904
+
905
+ label = Label.new( @shell, I18n.get( "gui.common.image" ) )
906
+ label.grid( "row"=>6, "column"=>1, "columnspan"=>2, "sticky"=>"w" )
907
+
908
+ label = Label.new( @shell, I18n.get( "gui.uploadcover.imagepath" ) )
909
+ label.grid( "row"=>7, "column"=>1, "sticky"=>"ew" )
910
+ image_frame = TkFrame.new( @shell )
911
+ image_frame.grid( "row"=>7, "column"=>2, "sticky"=>"ew" )
912
+ @image_path_lineedit = TextEdit.new( image_frame, @values["image_path"] )
913
+ @image_path_lineedit.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
914
+
915
+ @image_button = Button.new( image_frame, "..." )
916
+ @image_button.command( proc { browse_image() } )
917
+ @image_button.pack( "side"=>"right" )
918
+
919
+ buttons = create_action_buttons()
920
+ buttons.grid( "row"=>9, "column"=>1, "columnspan"=>4, "sticky"=>"ew" )
921
+
922
+ @shell.grid_rowconfigure( 5, "weight"=>1 )
923
+ @shell.grid_rowconfigure( 8, "weight"=>1 )
924
+ @shell.grid_columnconfigure( 2, "weight"=>1 )
925
+ end
926
+
927
+ def browse_image()
928
+ dirname = @image_path_lineedit.text().strip()
929
+ dirname = TK.empty_string?( dirname ) ? (ENV["HOME"] ? ENV["HOME"] : ".") : File.dirname( dirname )
930
+ image_path = Tk.getOpenFile( {
931
+ "parent" => @shell,
932
+ "title" => I18n.get( "gui.uploadcover.browseimage.title" ),
933
+ "initialdir" => dirname,
934
+ "filetypes" => [
935
+ [I18n.get( "gui.uploadcover.browseimage.images" ), ".jpg .JPG .png .PNG .bmp .BMP"],
936
+ [I18n.get( "gui.uploadcover.browseimage.allfiles" ), "*"]
937
+ ]
938
+ } )
939
+ @image_path_lineedit.set_text( image_path.strip() ) if ! TK.empty_string?( image_path )
940
+ end
941
+
942
+ def accept()
943
+ @values = {
944
+ "artist" => @artist_lineedit.text(),
945
+ "album" => @album_lineedit.text(),
946
+ "year" => @year_spinbox.value(),
947
+ "image_path" => @image_path_lineedit.text()
948
+ }
949
+ super()
950
+ end
951
+
952
+ end
953
+
954
+
955
+ class FixPagesDialog < BaseDialog
956
+
957
+ def initialize( values )
958
+ super( values )
959
+
960
+ @fetch_func = eval( @values["fetch_func"] )
961
+ @fix_func = eval( @values["fix_func"] )
962
+ @submit_func = eval( @values["submit_func"] )
963
+
964
+ set_size( 600, 400 )
965
+
966
+ @shell.title( "#{values["site_name"]} - #{values["title"]}" )
967
+
968
+ label = Label.new( @shell, I18n.get( "gui.common.url" ) )
969
+ label.grid( "row"=>1, "column"=>1 )
970
+ @url_lineedit = TextEdit.new( @shell, values["url"] )
971
+ @url_lineedit.grid( "row"=>1, "column"=>2, "columnspan"=>3, "sticky"=>"ew" )
972
+
973
+ page_frame = TkFrame.new( @shell )
974
+ page_frame.grid( "row"=>2, "column"=>1, "columnspan"=>4, "sticky"=>"nesw" )
975
+ bar = TkScrollbar.new( page_frame, "orient"=>"ver" )
976
+ bar.pack( "side"=>"right", "fill"=>"y" )
977
+ @page_text = TextArea.new( page_frame ) { yscrollcommand { |first, last| bar.set( first, last ) } }
978
+ @page_text.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
979
+ bar.command( proc { |*args| @page_text.yview( *args ) } )
980
+
981
+ buttons_frame = TkFrame.new( @shell )
982
+ @submit_button = Button.new( buttons_frame, I18n.get( "gui.common.submit" ) )
983
+ @submit_button.command( proc { submit_page() } )
984
+ @submit_button.pack( "side"=>"right" )
985
+ @fix_button = Button.new( buttons_frame, I18n.get( "gui.common.fix" ) )
986
+ @fix_button.command( proc { fix_page() } )
987
+ @fix_button.pack( "side"=>"right" )
988
+ @fetch_button = Button.new( buttons_frame, I18n.get( "gui.common.load" ) )
989
+ @fetch_button.command( proc { fetch_page() } )
990
+ @fetch_button.pack( "side"=>"right" )
991
+ buttons_frame.grid( "row"=>3, "column"=>1, "columnspan"=>4, "sticky"=>"ew" )
992
+
993
+ @shell.grid_rowconfigure( 2, "weight"=>1 )
994
+ @shell.grid_columnconfigure( 2, "weight"=>1 )
995
+ end
996
+
997
+ def fetch_page()
998
+ if (page_content = @fetch_func.call( @url_lineedit.value() ))
999
+ @original_content = page_content
1000
+ @original_url = @url_lineedit.text()
1001
+ @page_text.set_text( page_content )
1002
+ end
1003
+ end
1004
+
1005
+ def fix_page()
1006
+ @page_text.set_text( @fix_func.call( @page_text.text() ) ) if @original_content
1007
+ end
1008
+
1009
+ def submit_page()
1010
+ if @original_content != nil && @original_content != (page_content = @page_text.text())
1011
+ if @submit_func.call( @original_url, page_content )
1012
+ @original_content = page_content
1013
+ puts I18n.get( "gui.fixpages.success", @original_url )
1014
+ else
1015
+ puts I18n.get( "gui.fixpages.error", @original_url )
1016
+ end
1017
+ end
1018
+ end
1019
+
1020
+ end
1021
+
1022
+
1023
+ class SearchLyricsDialog < BaseDialog
1024
+
1025
+ def initialize( values )
1026
+ super( values )
1027
+
1028
+ set_size( 300, 140 )
1029
+
1030
+ @shell.title( I18n.get( "gui.searchlyrics.title" ) )
1031
+
1032
+ label = Label.new( @shell, I18n.get( "gui.searchlyrics.search" ) )
1033
+ label.grid( "row"=>1, "column"=>1, "columnspan"=>2, "sticky"=>"w" )
1034
+
1035
+ label = Label.new( @shell, I18n.get( "gui.common.artist" ) )
1036
+ label.grid( "row"=>2, "column"=>1 )
1037
+
1038
+ @artist_lineedit = TextEdit.new( @shell, @values["artist"] )
1039
+ @artist_lineedit.grid( "row"=>2, "column"=>2, "columnspan"=>2, "sticky"=>"ew" )
1040
+
1041
+ label = Label.new( @shell, I18n.get( "gui.common.song" ) )
1042
+ label.grid( "row"=>3, "column"=>1 )
1043
+ @title_lineedit = TextEdit.new( @shell, @values["title"] )
1044
+ @title_lineedit.grid( "row"=>3, "column"=>2, "columnspan"=>2, "sticky"=>"ew" )
1045
+
1046
+ label = Label.new( @shell, I18n.get( "gui.common.album" ) )
1047
+ label.grid( "row"=>4, "column"=>1 )
1048
+ @album_lineedit = TextEdit.new( @shell, @values["album"] )
1049
+ @album_lineedit.grid( "row"=>4, "column"=>2, "columnspan"=>2, "sticky"=>"ew" )
1050
+
1051
+ label = Label.new( @shell, I18n.get( "gui.common.year" ) )
1052
+ label.grid( "row"=>5, "column"=>1 )
1053
+ @year_spinbox = SpinBox.new( @shell, values["year"] )
1054
+ @year_spinbox.set_range( 1900, Date.today().year )
1055
+ @year_spinbox.grid( "row"=>5, "column"=>2, "columnspan"=>2, "sticky"=>"ew" )
1056
+
1057
+ buttons = create_action_buttons()
1058
+ buttons.grid( "row"=>7, "column"=>1, "columnspan"=>4, "sticky"=>"ew" )
1059
+
1060
+ @shell.grid_rowconfigure( 6, "weight"=>1 )
1061
+ @shell.grid_columnconfigure( 2, "weight"=>1 )
1062
+ @shell.grid_columnconfigure( 3, "weight"=>1 )
1063
+ end
1064
+
1065
+ def accept()
1066
+ @values = {
1067
+ "artist" => @artist_lineedit.text(),
1068
+ "title" => @title_lineedit.text(),
1069
+ "album" => @album_lineedit.text(),
1070
+ "year" => @year_spinbox.value(),
1071
+ }
1072
+ super()
1073
+ end
1074
+
1075
+ end
1076
+
1077
+
1078
+ class ShowLyricsDialog < BaseDialog
1079
+
1080
+ def initialize( values )
1081
+ super( values )
1082
+
1083
+ set_size( 350, 400 )
1084
+
1085
+ title = I18n.get( "gui.lyrics.title", @values["title"], @values["artist"] )
1086
+ title += " [#{@values["site_name"]}]" if @values["site_name"]
1087
+ @shell.title( title )
1088
+
1089
+ lyrics_frame = TkFrame.new( @shell )
1090
+ lyrics_frame.grid( "row"=>1, "column"=>1, "sticky"=>"nesw" )
1091
+ bar = TkScrollbar.new( lyrics_frame, "orient"=>"ver" )
1092
+ bar.pack( "side"=>"right", "fill"=>"y" )
1093
+ @lyrics_text = TextArea.new( lyrics_frame ) { yscrollcommand { |first, last| bar.set( first, last ) } }
1094
+ @lyrics_text.set_text( @values["lyrics"] )
1095
+ @lyrics_text.pack( "side"=>"left", "fill"=>"both", "expand"=>true )
1096
+ bar.command( proc { |*args| @lyrics_text.yview( *args ) } )
1097
+
1098
+ @shell.grid_rowconfigure( 1, "weight"=>1 )
1099
+ @shell.grid_columnconfigure( 1, "weight"=>1 )
1100
+ end
1101
+
1102
+ end
1103
+
1104
+ end