2 Copyright 2007-2008 Vincent Carmona
4 This file is part of ZiK.
6 ZiK is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 ZiK is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with ZiK; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 class Gui < Gtk::Window
23 bindtextdomain('ZiK',{:path=>Ldir})
28 ####################################
29 #-------Preferences-----------------
30 ####################################
35 ####################################
36 #-----------Gstreamer player--------
37 ####################################
38 @list1=Playlist.new(self,true)
39 @player=Player.new(@list1,@pref.player)
40 @player.volume=@pref.player['volume']/100
45 #*****************Explorer & list widgets****************
47 @treestore=Tree.new(String,String,String)
48 @path_explo=@treestore.refresh(@pref.dir,@pref.ext)
50 @iadd2plist_tree=Gtk::Image.new(Gtk::Stock::GO_FORWARD,Gtk::IconSize::MENU)
51 @badd2plist_tree=Gtk::ImageMenuItem.new(_('Add to playlist'))
52 @badd2plist_tree.image=@iadd2plist_tree
53 @badd2plist_tree.signal_connect("activate") {
56 @list1.add(@tree_select)
59 @list2.add(@tree_select)
62 @sep_tree=Gtk::SeparatorMenuItem.new
63 @brefresh_tree=Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
64 @brefresh_tree.signal_connect("activate") {@path_explo=@treestore.refresh(@pref.dir,@pref.ext)}
65 @badd_tree=Gtk::ImageMenuItem.new(Gtk::Stock::ADD)#Optimiser le code. -> ne pas rafraichir mais ajouter les nouveaux élements.
66 @badd_tree.signal_connect("activate") {
67 dialog=Gtk::FileChooserDialog.new(_("Add a directory"), self,
68 Gtk::FileChooser::ACTION_SELECT_FOLDER, nil,
69 [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL], [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
70 if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
71 @pref.dir.push(dialog.filename)
72 @path_explo=@treestore.refresh(@pref.dir,@pref.ext)
76 @brm_tree=Gtk::ImageMenuItem.new(Gtk::Stock::REMOVE)
77 @brm_tree.signal_connect("activate") {
79 @tree_select.selected_each{|model,path,iter|
81 collect.push(path.to_s.to_i)
87 collect.each{|i| @pref.dir.delete_at(i-a);a+=1}
88 @path_explo=@treestore.refresh(@pref.dir,@pref.ext)
90 puts "Delete only root directories"
93 @bclear_tree=Gtk::ImageMenuItem.new(Gtk::Stock::CLEAR)
94 @bclear_tree.signal_connect("activate") {@pref.dir.clear; @treestore.clear}
95 @bpref_tree=Gtk::ImageMenuItem.new(Gtk::Stock::PREFERENCES)
96 @bpref_tree.signal_connect("activate") {
97 dialog=Option.new(self,@pref.dir,@pref.ext,@border_width)
98 if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
101 @path_explo=@treestore.refresh(@pref.dir,@pref.ext)
105 @popup_tree=Gtk::Menu.new
106 @popup_tree.append(@badd2plist_tree)
107 @popup_tree.append(@sep_tree)
108 @popup_tree.append(@brefresh_tree)
109 @popup_tree.append(@badd_tree)
110 @popup_tree.append(@brm_tree)
111 @popup_tree.append(@bclear_tree)
112 @popup_tree.append(@bpref_tree)
115 @treeview=Gtk::TreeView.new(@treestore)
116 @tree_select=@treeview.selection
117 @tree_select.mode = Gtk::SELECTION_MULTIPLE
118 @renderer = Gtk::CellRendererText.new
119 @col = Gtk::TreeViewColumn.new(_("Browse"), @renderer, :text => 0)
120 @treeview.append_column(@col)
122 @treeview.signal_connect("button_press_event"){|widget, event|
124 @popup_tree.popup(nil, nil, event.button, event.time)
128 @wtree=Gtk::ScrolledWindow.new
129 @wtree.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
130 @wtree.add(@treeview)
131 ###---Buttons---------
132 @badd=Gtk::Button.new
133 @badd.add(Gtk::Image.new(Gtk::Stock::GO_FORWARD,Gtk::IconSize::BUTTON))
134 @badd.signal_connect('clicked') {
137 @list1.add(@tree_select)
140 @list2.add(@tree_select)
145 @bdel=Gtk::Button.new
146 @bdel.add(Gtk::Image.new(Gtk::Stock::GO_BACK,Gtk::IconSize::BUTTON))
147 @bdel.signal_connect('clicked') {
150 sel=@list1.del(@list1_select)
152 current_shuffle=@player.order[@player.current]
153 name=@list1.name[current_shuffle]
154 duration=(@list1.duration[current_shuffle].to_i)
155 @stitle.set_markup("<b>#{name}</b>")
158 @lduration.text='--:--'
161 @barpos.set_range(0,duration)
162 duration_s=(Time.at(duration).strftime("%M:%S"))
163 @lduration.text=duration_s
165 @list1.store.each{|model,path,iter|
173 @list2.del(@list2_select)
178 @bclear=Gtk::Button.new
179 @bclear.add(Gtk::Image.new(Gtk::Stock::CLEAR,Gtk::IconSize::BUTTON))
180 @bclear.signal_connect('clicked') {
194 ###---Lists-------------
196 @combolist=Gtk::ComboBox.new
197 @combolist.append_text(_('Listen to playlist'))
198 @combolist.append_text(_('Manage a secondary list'))
199 @combolist.append_text(_('Listen to radio'))
200 #@combolist.append_text(_('Lire un cd'))
202 @combolist.signal_connect('changed'){
203 case @combolist.active
205 @wradio.hide;@wlist2.hide;@mbox.hide;@wcd.hide;@wlist1.show;@showlistn=1
207 @wradio.hide;@wlist1.hide;@wcd.hide;@wlist2.show;@mbox.show;@showlistn=2
209 @wlist1.hide;@wlist2.hide;@mbox.hide;@wcd.hide;@wradio.show;@showlistn=3
211 @wlist1.hide;@wlist2.hide;@mbox.hide;@wradio.hide;@wcd.show;@showlistn=4
216 #@list1=Playlist.new(self,true) Already done
218 @irm_list1=Gtk::Image.new(Gtk::Stock::GO_BACK,Gtk::IconSize::MENU)
219 @brm_list1=Gtk::ImageMenuItem.new(_('Delete'))
220 @brm_list1.image=@irm_list1
221 @brm_list1.signal_connect("activate") {
222 sel=@list1.del(@list1_select)
225 @brefresh_list1=Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
226 @brefresh_list1.signal_connect("activate") {@list1.refresh}
227 @bexport_list1=Gtk::ImageMenuItem.new(Gtk::Stock::SAVE)
228 @bexport_list1.signal_connect("activate") {@list1.export(self)}
229 @bimport_list1=Gtk::ImageMenuItem.new(Gtk::Stock::ADD)
230 @bimport_list1.signal_connect("activate") {@list1.import(self);@player.add}
231 @bclear_list1=Gtk::ImageMenuItem.new(Gtk::Stock::CLEAR)
232 @bclear_list1.signal_connect("activate") {
233 @player.stop unless @player.radio?
237 @bsearch_list1=Gtk::ImageMenuItem.new(Gtk::Stock::FIND)
238 @bsearch_list1.signal_connect("activate"){
240 @wsearch_plist=Search::List.new unless Search.plist?
241 position=self.position+@boxlist.allocation.to_a
242 @wsearch_plist.search(position,@list1,@listview1)
244 @sep_list1=Gtk::SeparatorMenuItem.new
245 @bedit_list1=Gtk::ImageMenuItem.new(Gtk::Stock::EDIT)
246 @bedit_list1.signal_connect("activate") {EditTag.new(self,@list1_select,@list1,@border_width)}
247 @popup_list1=Gtk::Menu.new
248 @popup_list1.append(@brm_list1)
249 @popup_list1.append(@brefresh_list1)
250 @popup_list1.append(@bexport_list1)
251 @popup_list1.append(@bimport_list1)
252 @popup_list1.append(@bclear_list1)
253 @popup_list1.append(@bsearch_list1)
254 @popup_list1.append(@sep_list1)
255 @popup_list1.append(@bedit_list1)
256 @popup_list1.show_all
258 @listview1=Gtk::TreeView.new(@list1.store)
259 @listview1.headers_visible=false
260 @list1_select=@listview1.selection
261 @list1_select.mode = Gtk::SELECTION_MULTIPLE
262 @renderer=Gtk::CellRendererText.new
263 #@renderer.weight=Pango::WEIGHT_BOLD
264 #@col=Gtk::TreeViewColumn.new("Liste de lecture", @renderer, :text => 0, :weight_set => 1)
265 @renderer.background='Pink'#cf:/etc/X11/rgb.txt
266 @col=Gtk::TreeViewColumn.new("Liste de lecture", @renderer, :text => 0, :background_set => 1)
267 @listview1.append_column(@col)
269 @listview1.signal_connect("row-activated"){|view, path, column|
273 @listview1.signal_connect("button_press_event"){|widget, event|
275 @popup_list1.popup(nil, nil, event.button, event.time)
279 @wlist1=Gtk::ScrolledWindow.new
280 @wlist1.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
281 @wlist1.add(@listview1)
284 @list2=Playlist.new(self)
286 @irm_list2=Gtk::Image.new(Gtk::Stock::GO_BACK,Gtk::IconSize::MENU)
287 @brm_list2=Gtk::ImageMenuItem.new(_('Delete'))
288 @brm_list2.image=@irm_list2
289 @brm_list2.signal_connect("activate") {
290 sel=@list2.del(@list2_select)
293 @brefresh_list2=Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
294 @brefresh_list2.signal_connect("activate") {@list2.refresh}
295 @bexport_list2=Gtk::ImageMenuItem.new(Gtk::Stock::SAVE)
296 @bexport_list2.signal_connect("activate") {@list2.export(self)}
297 @bimport_list2=Gtk::ImageMenuItem.new(Gtk::Stock::ADD)
298 @bimport_list2.signal_connect("activate") {@list2.import(self);@player.add}
299 @bclear_list2=Gtk::ImageMenuItem.new(Gtk::Stock::CLEAR)
300 @bclear_list2.signal_connect("activate") {
301 @player.stop unless @player.radio?
305 @sep_list2=Gtk::SeparatorMenuItem.new
306 @bedit_list2=Gtk::ImageMenuItem.new(Gtk::Stock::EDIT)
307 @bedit_list2.signal_connect("activate") {EditTag.new(self,@list2_select,@list2,@border_width)}
308 @popup_list2=Gtk::Menu.new
309 @popup_list2.append(@brm_list2)
310 @popup_list2.append(@brefresh_list2)
311 @popup_list2.append(@bexport_list2)
312 @popup_list2.append(@bimport_list2)
313 @popup_list2.append(@bclear_list2)
314 @popup_list2.append(@sep_list2)
315 @popup_list2.append(@bedit_list2)
316 @popup_list2.show_all
318 @listview2=Gtk::TreeView.new(@list2.store)
319 @listview2.headers_visible=false
320 @list2_select=@listview2.selection
321 @list2_select.mode = Gtk::SELECTION_MULTIPLE
322 @renderer = Gtk::CellRendererText.new
323 @col=Gtk::TreeViewColumn.new("Gérer une liste", @renderer, :text => 0)
324 @listview2.append_column(@col)
326 @listview2.signal_connect("button_press_event"){|widget, event|
328 @popup_list2.popup(nil, nil, event.button, event.time)
332 @wlist2=Gtk::ScrolledWindow.new
333 @wlist2.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
334 @wlist2.add(@listview2)
337 @iup=Gtk::Image.new(Gtk::Stock::GO_UP,Gtk::IconSize::BUTTON)
340 @bup.signal_connect('clicked') {@list2.up(@list2_select)}
341 @idown=Gtk::Image.new(Gtk::Stock::GO_DOWN,Gtk::IconSize::BUTTON)
342 @bdown=Gtk::Button.new
344 @bdown.signal_connect('clicked') {@list2.down(@list2_select)}
345 @iexplo2m=Gtk::Image.new(Gtk::Stock::ADD,Gtk::IconSize::BUTTON)
346 @bexplo2m=Gtk::Button.new
347 @bexplo2m.image=@iexplo2m
348 @bexplo2m.signal_connect('clicked') {@list2.import(self)}
349 @im2explo=Gtk::Image.new(Gtk::Stock::SAVE,Gtk::IconSize::BUTTON)
350 @bm2explo=Gtk::Button.new
351 @bm2explo.image=@im2explo
352 @bm2explo.signal_connect('clicked') {@list2.export(self)}
353 @iplist2m=Gtk::Image.new(Gtk::Stock::COPY,Gtk::IconSize::BUTTON)
354 @bplist2m=Gtk::Button.new
355 @bplist2m.image=@iplist2m
356 @bplist2m.signal_connect('clicked') {@list2.copy(@list1)}
357 @im2plist=Gtk::Image.new(Gtk::Stock::PASTE,Gtk::IconSize::BUTTON)
358 @bm2plist=Gtk::Button.new
359 @bm2plist.image=@im2plist
360 @bm2plist.signal_connect('clicked') {
366 @mbox=Gtk::HBox.new(false, 0)
367 @mbox.pack_start(@bexplo2m, true, false)
368 @mbox.pack_start(@bm2explo, true, false)
369 @mbox.pack_start(@bup, true, false)
370 @mbox.pack_start(@bdown, true, false)
371 @mbox.pack_start(@bplist2m, true, false)
372 @mbox.pack_start(@bm2plist, true, false)
375 @radiostore=Gtk::ListStore.new(String,String)
376 @pref.radio.each{|key,value|
377 child=@radiostore.append
382 @iadd_radio=Gtk::Image.new(Gtk::Stock::GO_FORWARD,Gtk::IconSize::MENU)
383 @badd_radio=Gtk::ImageMenuItem.new(_('Add a radio'))
384 @badd_radio.image=@iadd_radio
385 @badd_radio=Gtk::ImageMenuItem.new(Gtk::Stock::GO_FORWARD)
386 @irm_radio=Gtk::Image.new(Gtk::Stock::GO_BACK,Gtk::IconSize::MENU)
387 @brm_radio=Gtk::ImageMenuItem.new(_('Delete a radio'))
388 @brm_radio.image=@irm_radio
389 @badd_radio.signal_connect("activate") {rm_radio}
390 @bclear_radio=Gtk::ImageMenuItem.new(Gtk::Stock::CLEAR)
391 @bclear_radio.signal_connect("activate") {
392 @player.stop if @player.radio?
396 @sep_radio=Gtk::SeparatorMenuItem.new
397 @bedit_radio=Gtk::ImageMenuItem.new(Gtk::Stock::EDIT)#Gtk::MenuItem.new('Éditer')
398 @bedit_radio.signal_connect("activate") {edit_radio(@radio_select.selected)}
399 @popup_radio=Gtk::Menu.new
400 @popup_radio.append(@badd_radio)
401 @popup_radio.append(@brm_radio)
402 @popup_radio.append(@bclear_radio)
403 @popup_radio.append(@sep_radio)
404 @popup_radio.append(@bedit_radio)
405 @popup_radio.show_all
407 @radioview=Gtk::TreeView.new(@radiostore)
408 @radioview.headers_visible=false
409 @radio_select=@radioview.selection
410 @radio_select.mode = Gtk::SELECTION_SINGLE
411 @renderer = Gtk::CellRendererText.new
412 @col=Gtk::TreeViewColumn.new("Écouter la radio", @renderer, :text => 0)
413 @radioview.append_column(@col)
415 @radioview.signal_connect("row-activated"){@player.stop;play_radio}
416 @radioview.signal_connect("button_press_event"){|widget, event|
418 @popup_radio.popup(nil, nil, event.button, event.time)
422 @wradio=Gtk::ScrolledWindow.new
423 @wradio.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
424 @wradio.add(@radioview)
427 @cdstore=Gtk::ListStore.new(String)
428 @cdview=Gtk::TreeView.new(@cdstore)
429 @cdview.headers_visible=false
430 @renderer = Gtk::CellRendererText.new
431 @col=Gtk::TreeViewColumn.new("Lire un cd", @renderer, :text => 0)
432 @cdview.append_column(@col)
434 @wcd=Gtk::ScrolledWindow.new
435 @wcd.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
439 @boxlist=Gtk::VBox.new(false, 0)
440 @boxlist.pack_start(@combolist, false, false, 0)
441 @boxlist.pack_start(@wlist1)
442 @boxlist.pack_start(@wlist2)
443 @boxlist.pack_start(@wradio)
444 @boxlist.pack_start(@wcd)
445 @boxlist.pack_start(@mbox,false, false, 0)
447 ###---Containers--------
448 @table=Gtk::Table.new(5,2)
449 @table.column_spacings=(5)
450 @table.attach(@wtree, 0, 1, 0, 5)
451 @table.attach(@badd, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK)
452 @table.attach(@bdel, 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK)
453 @table.attach(@bclear, 1, 2, 3, 4, Gtk::SHRINK, Gtk::SHRINK)
455 @paned=Gtk::HPaned.new
456 #@paned.border_width=@border_width
457 @paned.position=@pref.gui['paned_position']
459 @paned.add2(@boxlist)
460 #**************Player buttons*********************
462 @iexplo=Gtk::Image.new('gtk-directory',Gtk::IconSize::BUTTON)#Gtk::Stock::DIRECTORY is not (yet?) initialized.
463 @bexplo=Gtk::Button.new
464 @bexplo.image=@iexplo
465 @bexplo.signal_connect('clicked') {
466 if @pref.gui['showexplo']
468 unless @pref.gui['showlist']
469 @paned.hide;self.resize(400,100)
472 if @pref.gui['showlist']
474 @pref.gui['width']=s[0];@pref.gui['height']=s[1]
476 @paned.child1.show;@paned.show;self.resize(@pref.gui['width'],@pref.gui['height'])
478 @pref.gui['showexplo']=!@pref.gui['showexplo']
481 @ilist=Gtk::Image.new(Gtk::Stock::INDEX,Gtk::IconSize::BUTTON)
482 @blist=Gtk::Button.new
484 @blist.signal_connect('clicked') {
485 if @pref.gui['showlist']
487 unless @pref.gui['showexplo']
488 @paned.hide;self.resize(400,100)
491 if @pref.gui['showexplo']
493 @pref.gui['width']=s[0];@pref.gui['height']=s[1]
495 @paned.child2.show;@paned.show;self.resize(@pref.gui['width'],@pref.gui['height'])
497 @pref.gui['showlist']=!@pref.gui['showlist']
500 @stitle=Gtk::Label.new()
503 @vtitle=Gtk::Frame.new#('Titre en cours')
506 @barvol=Gtk::VScale.new(0,100,1)
508 @barvol.inverted=true
509 @barvol.value=@pref.player['volume']
510 @barvol.signal_connect('value-changed'){@player.volume=@barvol.value/100}
513 @wvol=Gtk::Window.new
514 @wvol.decorated=false
515 @wvol.skip_taskbar_hint=true
516 @wvol.skip_pager_hint=true
517 @wvol.set_size_request(40,200)
518 @wvol.resizable=false
519 #@wvol.transient_for=(self)
521 @wvol.signal_connect("focus-out-event"){@wvol.hide}
523 @ivol=Gtk::Image.new(File.join(Pdir,'volume.xpm'))
524 @bvol=Gtk::Button.new
526 @barvol.can_focus=true
527 @bvol.signal_connect('clicked') {
528 position=self.position+@bvol.allocation.to_a
529 @wvol.move(position[0]+position[2]-40,position[1]+position[3])
530 @barvol.value=@player.volume*100
534 @boxh=Gtk::HBox.new(false)
535 #@boxh.border_width=@border_width
536 @boxh.pack_start(@bexplo, false, false)
537 @boxh.pack_start(@blist, false, false)
538 @boxh.pack_start(@vtitle, true, true)
539 @boxh.pack_start(@bvol, false, false)
542 @iprev=Gtk::Image.new(Gtk::Stock::MEDIA_PREVIOUS,Gtk::IconSize::BUTTON)
543 @bprev= Gtk::Button.new
545 @bprev.signal_connect('clicked'){prev unless @player.radio?}
546 @istop=Gtk::Image.new(Gtk::Stock::MEDIA_STOP,Gtk::IconSize::BUTTON)
547 @bstop= Gtk::Button.new
549 @bstop.signal_connect('clicked'){@player.stop}
550 @iplay=Gtk::Image.new(Gtk::Stock::MEDIA_PLAY,Gtk::IconSize::BUTTON)
551 @bplay= Gtk::Button.new
553 @bplay.signal_connect('clicked'){
558 @player.stop if @player.radio?
562 @ipause=Gtk::Image.new(Gtk::Stock::MEDIA_PAUSE,Gtk::IconSize::BUTTON)
563 @bpause=Gtk::Button.new
564 @bpause.image=@ipause
565 @bpause.signal_connect('clicked'){@player.pause}
566 @inext=Gtk::Image.new(Gtk::Stock::MEDIA_NEXT,Gtk::IconSize::BUTTON)
567 @bnext= Gtk::Button.new
569 @bnext.signal_connect('clicked'){next_s unless @player.radio?}
572 @lposition=Gtk::Label.new('--:--')
573 @barpos=Gtk::HScale.new
574 @barpos.draw_value=false
575 @lduration=Gtk::Label.new('--:--')
576 @barpos.signal_connect('button_press_event'){@seeking=true;false}
577 @barpos.signal_connect('button_release_event'){@player.position=@barpos.value.to_i;@seeking=false}
579 @bplayer = Gtk::HBox.new(false)
580 #@bplayer.border_width=@border_width
581 @bplayer.pack_start(@bprev, false, false)
582 @bplayer.pack_start(@bstop, false, false)
583 @bplayer.pack_start(@bplay, false, false)
584 @bplayer.pack_start(@bpause, false, false)
585 @bplayer.pack_start(@bnext, false, false)
586 @bplayer.pack_start(@lposition, false, false)
587 @bplayer.pack_start(@barpos, true, true)
588 @bplayer.pack_start(@lduration, false, false)
589 #*************Quit************************
590 @bclose= Gtk::Button.new(Gtk::Stock::QUIT)
591 @bclose.signal_connect('clicked') {quit}
592 #*************Menu******************
593 ###----Musik menu-------
594 @play_it=Gtk::ImageMenuItem.new(Gtk::Stock::MEDIA_PLAY)
595 @play_it.signal_connect('activate'){@player.play}
596 @stop_it=Gtk::ImageMenuItem.new(Gtk::Stock::MEDIA_STOP)
597 @stop_it.signal_connect('activate'){@player.stop}
598 @prev_it=Gtk::ImageMenuItem.new(Gtk::Stock::MEDIA_PREVIOUS)
599 @prev_it.signal_connect('activate'){prev}
600 @next_it=Gtk::ImageMenuItem.new(Gtk::Stock::MEDIA_NEXT)
601 @next_it.signal_connect('activate'){next_s}
602 @sep=Gtk::SeparatorMenuItem.new
603 @sep2=Gtk::SeparatorMenuItem.new
604 @shuffle_it=Gtk::CheckMenuItem.new(_('Shuffle'));
605 @shuffle_it.active=@pref.player['shuffle']
606 @shuffle_it.signal_connect("toggled"){@pref.player['shuffle']=!@pref.player['shuffle'];@player.toggle_shuffle}
607 @repeat_it=Gtk::CheckMenuItem.new(_('Repeat'));#repeat or loopback or????
608 @repeat_it.active=@pref.player['repeat']
609 @repeat_it.signal_connect("toggled"){
610 @pref.player['repeat']=!@pref.player['repeat'];@player.repeat=@pref.player['repeat']
612 @playonstart_it=Gtk::CheckMenuItem.new(_('Play on start'))
613 @playonstart_it.active=@pref.player['playonstart']
614 @playonstart_it.signal_connect("toggled"){@pref.player['playonstart']=!@pref.player['playonstart']}
615 @quit_it=Gtk::ImageMenuItem.new(Gtk::Stock::QUIT)
616 @quit_it.signal_connect('activate'){quit}
618 @menu_musiq=Gtk::Menu.new
619 @menu_musiq.append(@play_it)
620 @menu_musiq.append(@stop_it)
621 @menu_musiq.append(@prev_it)
622 @menu_musiq.append(@next_it)
623 @menu_musiq.append(@sep)
624 @menu_musiq.append(@shuffle_it)
625 @menu_musiq.append(@repeat_it)
626 @menu_musiq.append(@playonstart_it)
627 @menu_musiq.append(@sep2)
628 @menu_musiq.append(@quit_it)
629 ###----Explorateur menu------
630 @tree_refresh_it=Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
631 @tree_refresh_it.signal_connect("activate") {@path_explo=@treestore.refresh(@pref.dir,@pref.ext)}
632 @moddir_it=Gtk::ImageMenuItem.new(Gtk::Stock::PREFERENCES)
633 @moddir_it.signal_connect("activate") {
634 dialog=Option.new(self,@pref.dir,@pref.ext,@border_width)
635 if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
638 @path_explo=@treestore.refresh(@pref.dir,@pref.ext)
642 @search_it=Gtk::ImageMenuItem.new(Gtk::Stock::FIND)
643 @search_it.signal_connect("activate") {
644 @wsearch_explo=Search::Explo.new(@player,@list1,@list2,@border_width) unless Search.explo?
645 position=self.position+@wtree.allocation.to_a
646 @wsearch_explo.search(position,@path_explo)
649 @menu_explo=Gtk::Menu.new
650 @menu_explo.append(@tree_refresh_it)
651 @menu_explo.append(@moddir_it)
652 @menu_explo.append(@search_it)
653 ###----Playlist menu------
654 @list_refresh_it=Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
655 @list_refresh_it.signal_connect("activate") {@list1.refresh}
656 @import_it=Gtk::ImageMenuItem.new(Gtk::Stock::ADD)
657 @import_it.signal_connect("activate") {@list1.import(self);@player.add}
658 @export_it=Gtk::ImageMenuItem.new(Gtk::Stock::SAVE)
659 @export_it.signal_connect("activate") {@list1.export(self)}
660 @del_it=Gtk::ImageMenuItem.new(Gtk::Stock::CLEAR)
661 @del_it.signal_connect("activate") {@player.stop;@player.del_all;@list1.del_all}
662 @search_plit=Gtk::ImageMenuItem.new(Gtk::Stock::FIND)
663 @search_plit.signal_connect("activate"){
665 @wsearch_plist=Search::List.new unless Search.plist?
666 position=self.position+@boxlist.allocation.to_a
667 @wsearch_plist.search(position,@list1,@listview1)
669 @sep=Gtk::SeparatorMenuItem.new
670 @list_edit_it=Gtk::ImageMenuItem.new(Gtk::Stock::EDIT)
671 @list_edit_it.signal_connect("activate") {
672 @list1_select.select_all
673 EditTag.new(self,@list1_select,@list1,@border_width)
676 @menu_list=Gtk::Menu.new
677 @menu_list.append(@list_refresh_it)
678 @menu_list.append(@import_it)
679 @menu_list.append(@export_it)
680 @menu_list.append(@del_it)
681 @menu_list.append(@search_plit)
682 @menu_list.append(@sep)
683 @menu_list.append(@list_edit_it)
685 #Faire un fichier help_lc.rb par langue
686 #Utiliser GetText.locale afin de connaitre lc
687 @help_it2=Gtk::ImageMenuItem.new(Gtk::Stock::HELP)
688 @help_it2.signal_connect("activate"){Help.new(self)}
689 @about_it=Gtk::ImageMenuItem.new(Gtk::Stock::ABOUT)
690 f=File.open(File.join(Ddir,'COPYING'))
696 @about_it.signal_connect("activate") {
697 Gtk::AboutDialog.show(self, {'name'=>'ZiK',
699 'copyright'=>'Copyright 2007-2008 Vincent Carmona',
700 'comments'=>_('Audio player'),
701 'website'=>'http://zik.rubyforge.org/',
703 'authors'=>["Vincent Carmona <vinc-mai@caramail.com>"],
704 'translator_credits'=>"Français: Vincent Carmona\n",
705 'logo'=>Gdk::Pixbuf.new(File.join(Pdir,'ZiK3.png'))})
706 #name do not work -> Bug 496689?
709 @menu_help=Gtk::Menu.new
710 @menu_help.append(@help_it2)
711 @menu_help.append(@about_it)
712 ###----Menu bar------------
713 @musiq_it=Gtk::MenuItem.new(_('Music'))
714 @musiq_it.set_submenu(@menu_musiq)
715 @list_it=Gtk::MenuItem.new(_('Playlist'))
716 @list_it.set_submenu(@menu_list)
717 @config_it=Gtk::MenuItem.new(_('Browser'))
718 @config_it.set_submenu(@menu_explo)
719 @help_it=Gtk::MenuItem.new(_('Help'))
720 @help_it.set_submenu(@menu_help)
722 @menu_bar=Gtk::MenuBar.new
723 @menu_bar.append(@musiq_it)
724 @menu_bar.append(@config_it)
725 @menu_bar.append(@list_it)
726 @menu_bar.append(@help_it)
727 #****************Acceleration Keys*********************
728 #connect media key 0xa2(play/pause)
729 @accel=Gtk::AccelGroup.new
730 @accel.connect(Gdk::Keyval::GDK_p, nil,Gtk::ACCEL_VISIBLE){
741 @accel.connect(Gdk::Keyval::GDK_s, nil,Gtk::ACCEL_VISIBLE){@player.stop}
742 @accel.connect(Gdk::Keyval::GDK_b, nil,Gtk::ACCEL_VISIBLE){prev}
743 @accel.connect(Gdk::Keyval::GDK_n, nil,Gtk::ACCEL_VISIBLE){next_s}
744 @accel.connect(Gdk::Keyval::GDK_Down, Gdk::Window::CONTROL_MASK,Gtk::ACCEL_VISIBLE){@player.vol_down}
745 @accel.connect(Gdk::Keyval::GDK_Up, Gdk::Window::CONTROL_MASK,Gtk::ACCEL_VISIBLE){@player.vol_up}
746 @accel.connect(Gdk::Keyval::GDK_f, Gdk::Window::CONTROL_MASK, Gtk::ACCEL_VISIBLE){
748 @wsearch_plist=Search::List.new unless Search.plist?
749 position=self.position+@boxlist.allocation.to_a
750 @wsearch_plist.search(position,@list1,@listview1)
752 #***************Main window********************
755 @vbox.pack_start( @menu_bar, false, false, 0)
756 @vbox.pack_start(@paned)
757 @vbox.pack_start(@boxh, false, false)
758 @vbox.pack_start(@bplayer, false, false)
759 @vbox.pack_start(@bclose, false, false)
760 #Pre show the widgets
762 @wlist2.hide;@mbox.hide;@wradio.hide;@wcd.hide
763 if !@pref.gui['showexplo']
766 if !@pref.gui['showlist']
770 super(Gtk::Window::TOPLEVEL)
771 self.signal_connect("grab-focus"){|widget, event| puts 'grab';@wvol.hide}
772 self.signal_connect("delete_event") {quit;true}
773 self.add_accel_group(@accel)
774 self.set_default_size(500,600)
775 if @pref.gui['showlist'] or @pref.gui['explo']
776 self.resize(@pref.gui['width'],@pref.gui['height'])
780 self.move(@pref.gui['xposition'],@pref.gui['yposition'])
782 @icon_Z = Gdk::Pixbuf.new(File.join(Pdir,'ZiK.svg'))
787 @tray=SysTray.new(self,@player)
789 play if @pref.player['playonstart']
793 #************Refresh the datas when playing****************************
796 @pref.player['current']=@player.current
797 current_shuffle=@player.order[@player.current]
798 unless current_shuffle.nil?
799 name=@list1.name[current_shuffle]
800 duration=(@list1.duration[current_shuffle].to_i)
801 @stitle.set_markup("<b>#{name}</b>")
804 @lduration.text='--:--'
807 @barpos.set_range(0,duration)
808 duration_s=(Time.at(duration).strftime("%M:%S"))
809 @lduration.text=duration_s
811 @list1.store.each{|model,path,iter|
820 Gtk.timeout_add(400){
821 unless @pref.player['current']==@player.current
822 @pref.player['current']=@player.current
823 current_shuffle=@player.order[@player.current]
824 unless current_shuffle.nil?
825 name=@list1.name[current_shuffle]
826 @stitle.set_markup("<b>#{name}</b>")
827 duration=(@list1.duration[current_shuffle].to_i)
830 @lduration.text='--:--'
833 @barpos.set_range(0,duration)
834 duration_s=(Time.at(duration).strftime("%M:%S"))
835 @lduration.text=duration_s
837 @list1.store.each{|model,path,iter|#In the playlist view, set the current song to bold
846 position=@player.position
849 @barpos.value=position
852 @lposition.text=Time.at(position).strftime("%M:%S")
854 @lposition.text='--:--'
861 def play_radio #Gérer les erreurs du type "Gst error" -> utiliser array[1..end]
862 unless @radio_select.selected.nil?
863 url=@radio_select.selected[1]
865 when /^http:\/\/.*\.m3u$/i
866 plist=fetch_playlist(url)
867 tmp=Tempfile.new('ZiKPlist')
873 when /^http:\/\/.*\.pls$/i
874 plist=fetch_playlist(url)
875 tmp=Tempfile.new('ZiKPlist')
881 when /^http:\/\/.*\.asx$/i
882 plist=fetch_playlist(url)
883 tmp=Tempfile.new('ZiKPlist')
892 radio_name=@radio_select.selected[0]
893 @stitle.set_markup("<b>#{radio_name}</b>")
894 @lduration.text='--:--'
898 @player.play_radio(stream[i])
901 @player.play_radio(stream[i]) if i < l
907 play unless @player.playing?
912 play unless @player.playing?
919 entry2=Gtk::Entry.new
921 dialog = Gtk::Dialog.new(_("Add a radio"),self,Gtk::Dialog::DESTROY_WITH_PARENT,[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL], [Gtk::Stock::APPLY, Gtk::Dialog::RESPONSE_ACCEPT])
922 dialog.vbox.add(entry)
923 dialog.vbox.add(entry2)
925 if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
926 @pref.radio[entry.text]=entry2.text
927 child=@radiostore.append
928 child[0]=entry.text;child[1]=entry2.text
934 unless @radio_select.selected.nil?
935 @pref.radio.delete_at(@radio_select.selected.path.to_str.to_i)
936 @radiostore.remove(@radio_select.selected)
940 def edit_radio(selection)
941 unless selection.nil?
943 entry.text=selection[0]
944 entry2=Gtk::Entry.new
945 entry2.text=selection[1]
946 dialog = Gtk::Dialog.new(_("Edit a radio"),self,Gtk::Dialog::DESTROY_WITH_PARENT,[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL], [Gtk::Stock::APPLY, Gtk::Dialog::RESPONSE_ACCEPT])
947 dialog.vbox.add(entry)
948 dialog.vbox.add(entry2)
950 if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
951 @pref.radio.delete(selection[0])
952 @pref.radio[entry.text]=entry2.text
953 selection[0]=entry.text;selection[1]=entry2.text
962 @pref.player['volume']=(@player.volume*100)
964 @pref.gui['xposition']=pos[0]
965 @pref.gui['yposition']=pos[1]
966 if @pref.gui['showlist'] or @pref.gui['explo']
968 @pref.gui['width']=s[0]
969 @pref.gui['height']=s[1]
971 @pref.gui['paned_position']=@paned.position