zik 0.16.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/ChangeLog +222 -0
- data/INSTALL +34 -0
- data/Makefile.in +199 -0
- data/README +53 -0
- data/ZiK.desktop +11 -0
- data/ZiK.rb +377 -0
- data/configure +269 -0
- data/dependencies +142 -0
- data/doc/COPYING +340 -0
- data/doc/ChangeLog +222 -0
- data/doc/html/fr/index.html +128 -0
- data/doc/html/index.html +126 -0
- data/doc/html/pix/ZiK3.png +0 -0
- data/doc/html/pix/capture.png +0 -0
- data/doc/html/pix/capture_cd.png +0 -0
- data/doc/html/pix/capture_compact.png +0 -0
- data/doc/html/pix/capture_radio.png +0 -0
- data/doc/html/pix/icon.png +0 -0
- data/doc/html/pix/logo.png +0 -0
- data/doc/html/styles/main.css +47 -0
- data/doc/man/manpage.1 +43 -0
- data/gui/assistant.rb +133 -0
- data/gui/cdgui.rb +54 -0
- data/gui/common.rb +56 -0
- data/gui/config.rb +120 -0
- data/gui/edit.rb +413 -0
- data/gui/error.rb +124 -0
- data/gui/gui.rb +1383 -0
- data/gui/mod.rb +239 -0
- data/gui/preference.rb +496 -0
- data/gui/progress.rb +50 -0
- data/gui/radiogui.rb +404 -0
- data/gui/search.rb +249 -0
- data/gui/socket.rb +107 -0
- data/mod/brainz.rb +76 -0
- data/mod/brainz/dialogs.rb +132 -0
- data/mod/brainz/functions.rb +55 -0
- data/mod/brainz/ofa.rb +76 -0
- data/mod/brainz/song.rb +139 -0
- data/mod/brainz/widget.rb +34 -0
- data/mod/cover.rb +90 -0
- data/mod/cover/application-x-cd-image.svg +666 -0
- data/mod/cover/config.rb +79 -0
- data/mod/cover/configwidget.rb +35 -0
- data/mod/cover/widget.rb +147 -0
- data/mod/hotkeys.rb +137 -0
- data/mod/hotkeys/config.rb +84 -0
- data/mod/hotkeys/configwidget.rb +93 -0
- data/mod/interact.rb +131 -0
- data/mod/interact/configwidget.rb +107 -0
- data/mod/interact/interaction.rb +79 -0
- data/mod/notify.rb +128 -0
- data/mod/notify/config.rb +96 -0
- data/mod/notify/configwidget.rb +76 -0
- data/mod/notify/window.rb +56 -0
- data/mod/trayicon.rb +83 -0
- data/mod/trayicon/config.rb +79 -0
- data/mod/trayicon/configwidget.rb +35 -0
- data/mod/trayicon/icon.rb +99 -0
- data/pix/ZiK.svg +78 -0
- data/pix/ZiK3.png +0 -0
- data/pix/assistant/capture.png +0 -0
- data/pix/gtk-directory.svg +287 -0
- data/pix/media-cdrom.svg +292 -0
- data/pix/network-wireless.svg +429 -0
- data/pix/player_play.svg +286 -0
- data/pix/sound.svg +244 -0
- data/pix/sound_directory.svg +464 -0
- data/player/cdplayer.rb +108 -0
- data/player/player.rb +132 -0
- data/player/radioplayer.rb +124 -0
- data/playlist/cdlist.rb +140 -0
- data/playlist/common.rb +343 -0
- data/playlist/editlist.rb +50 -0
- data/playlist/export.rb +108 -0
- data/playlist/playlist.rb +143 -0
- data/playlist/radiolist.rb +148 -0
- data/playlist/song.rb +122 -0
- data/po/ZiK.pot +622 -0
- data/po/fr/ZiK.po +658 -0
- data/zik +2 -0
- metadata +265 -0
- metadata.gz.sig +0 -0
data/gui/mod.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright 2007-2011 Vincent Carmona
|
4
|
+
vinc4mai@gmail.com
|
5
|
+
|
6
|
+
This file is part of ZiK.
|
7
|
+
|
8
|
+
ZiK is free software; you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU General Public License as published by
|
10
|
+
the Free Software Foundation; either version 2 of the License, or
|
11
|
+
(at your option) any later version.
|
12
|
+
|
13
|
+
ZiK is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU General Public License
|
19
|
+
along with ZiK; if not, write to the Free Software
|
20
|
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
+
=end
|
22
|
+
|
23
|
+
class ModNotUniqueId < Exception
|
24
|
+
end
|
25
|
+
|
26
|
+
class ModError < Error
|
27
|
+
#Error superclass for module not to be directly used.
|
28
|
+
def initialize(mod, type, message, user, description)
|
29
|
+
super(type, message, user, "#{mod.title}\n"+(description||message))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ModErrorInfo < ModError
|
34
|
+
def initialize(mod, message, user=false, description=nil)
|
35
|
+
print "[#{mod.id}]: "
|
36
|
+
super(mod, ModErrorINFO, message, user, description)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ModErrorWarning < ModError
|
41
|
+
def initialize(mod, message, user=false, description=nil)
|
42
|
+
$stderr.print "[#{mod.id}]: "
|
43
|
+
super(mod, ModErrorWARNING, message, user, description)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class ModErrorError < ModError
|
48
|
+
def initialize(mod, message, user=false, description=nil)
|
49
|
+
$stderr.print "[#{mod.id}]: "
|
50
|
+
super(mod, ModErrorERROR, message, user, description)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class ModErrorLoadError < ModError
|
55
|
+
@@stock=[]
|
56
|
+
attr_reader :mod, :message
|
57
|
+
|
58
|
+
def ModErrorLoadError.show_all
|
59
|
+
if $show_errors
|
60
|
+
unless @@stock.empty?
|
61
|
+
message=_("Some module cannot be loaded.")
|
62
|
+
@@stock.each{|error| message+="\n\n#{error.mod.title}\n#{error.message}"}
|
63
|
+
dialog=Gtk::MessageDialog.new(@@zik, Gtk::Dialog::MODAL|Gtk::Dialog::DESTROY_WITH_PARENT,
|
64
|
+
Gtk::MessageDialog::ERROR, Gtk::MessageDialog::BUTTONS_CLOSE, message)
|
65
|
+
dialog.run; dialog.destroy
|
66
|
+
@@stock=[]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def initialize(mod, type, message)
|
72
|
+
@mod=mod; @message=message
|
73
|
+
@@stock.push(self)
|
74
|
+
$stderr.print "[#{mod.id}]: "
|
75
|
+
super(mod, ModErrorLOAD_ERROR, message, false)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class Mod
|
80
|
+
#Class used to implement a ZiK module (plugin).
|
81
|
+
|
82
|
+
###Internal use
|
83
|
+
@@ids=[]; @@global=true
|
84
|
+
@@all=[]; @@own=[]; @@user=[]
|
85
|
+
|
86
|
+
def Mod.global=(tf)
|
87
|
+
@@global=tf
|
88
|
+
end
|
89
|
+
|
90
|
+
def Mod.all
|
91
|
+
@@all
|
92
|
+
end
|
93
|
+
|
94
|
+
def Mod.own
|
95
|
+
@@own
|
96
|
+
end
|
97
|
+
|
98
|
+
def Mod.user
|
99
|
+
@@user
|
100
|
+
end
|
101
|
+
|
102
|
+
def Mod.zik=(zik)
|
103
|
+
@@zik=zik
|
104
|
+
end
|
105
|
+
|
106
|
+
###External use
|
107
|
+
attr_reader :id, :title, :description, :author, :license
|
108
|
+
|
109
|
+
def initialize(id, title, description, author, license)
|
110
|
+
@id=id#Internal id. Must be unique.
|
111
|
+
raise ModNotUniqueId if @@ids.include?(@id)
|
112
|
+
@@ids.push(@id)
|
113
|
+
@loaded=false
|
114
|
+
@title=title#Name of the module
|
115
|
+
@description=description#Short description of the module
|
116
|
+
@author=author#A string used in credits (name1 <contact email>, name2)
|
117
|
+
@license=license#A short string ('GPL-2', 'BSD'...)
|
118
|
+
@@all.push(self)
|
119
|
+
@@global ? @@own.push(self) : @@user.push(self)
|
120
|
+
end
|
121
|
+
|
122
|
+
def pack(widget, start=true, expand=true, fill=true, padding=0)
|
123
|
+
#Use this method to show a widget in the main interface.
|
124
|
+
unless defined?(@@hbox)
|
125
|
+
@@expander=Gtk::Expander.new(_('Modules'))
|
126
|
+
@@expander.spacing=$border
|
127
|
+
@@expander.signal_connect('notify::expanded'){|widget, foo|
|
128
|
+
if widget.expanded?
|
129
|
+
@@hbox.show
|
130
|
+
else
|
131
|
+
@@hbox.hide
|
132
|
+
@@zik.resize(@@zik.size[0], 1) if @@zik.selectview.active==View::COMPACT
|
133
|
+
end
|
134
|
+
}
|
135
|
+
@@hbox=Gtk::HBox.new
|
136
|
+
zik.vbox.pack_start(@@expander, false, false)
|
137
|
+
zik.vbox.pack_start(@@hbox, false, false)
|
138
|
+
position=2; position+=1 if $cd; position+=1 if $radio
|
139
|
+
zik.vbox.reorder_child(@@expander, position)
|
140
|
+
zik.vbox.reorder_child(@@hbox, position+1)
|
141
|
+
@@expander.show
|
142
|
+
end
|
143
|
+
|
144
|
+
if start
|
145
|
+
@@hbox.pack_start(widget, expand, fill, padding)
|
146
|
+
else
|
147
|
+
@@hbox.pack_end(widget, expand, fill, padding)
|
148
|
+
end
|
149
|
+
@@expander.activate
|
150
|
+
end
|
151
|
+
|
152
|
+
def menu_add(widget)
|
153
|
+
#Use this method to show a widget under ZiK module menu.
|
154
|
+
unless defined?(@@menu)
|
155
|
+
@@menu=Gtk::Menu.new
|
156
|
+
item=Gtk::MenuItem.new(_('Modules')).show
|
157
|
+
item.set_submenu(@@menu)
|
158
|
+
@@zik.menu_bar.append(item)
|
159
|
+
end
|
160
|
+
@@menu.show
|
161
|
+
@@menu.append(widget)
|
162
|
+
end
|
163
|
+
|
164
|
+
def menu_hide
|
165
|
+
#Destroy module menu if it is empty
|
166
|
+
if defined?(@@menu)
|
167
|
+
@@menu.hide if @@menu.children.empty?
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def list_cmenu_add(widget)
|
172
|
+
#Use this method to show a widget in the playlist context menu.
|
173
|
+
unless defined?(@@cmenu_list)
|
174
|
+
@@cmenu_list=Gtk::Menu.new
|
175
|
+
it=Gtk::MenuItem.new(_("Modules"))
|
176
|
+
@@zik.cm_list.append(Gtk::SeparatorMenuItem.new)
|
177
|
+
@@zik.cm_list.append(it)
|
178
|
+
it.set_submenu(@@cmenu_list)
|
179
|
+
it.show
|
180
|
+
@@cmenu_list.show
|
181
|
+
end
|
182
|
+
@@cmenu_list.append(widget)
|
183
|
+
end
|
184
|
+
|
185
|
+
def expander
|
186
|
+
#Use this method to get the expander. Can return nil.
|
187
|
+
defined?(@@expander) ? @@expander : nil
|
188
|
+
end
|
189
|
+
|
190
|
+
def zik
|
191
|
+
@@zik
|
192
|
+
end
|
193
|
+
|
194
|
+
def loaded?
|
195
|
+
@loaded
|
196
|
+
end
|
197
|
+
|
198
|
+
###Methods you may want to redefine.
|
199
|
+
|
200
|
+
def init(input)
|
201
|
+
#Called when ZiK starts
|
202
|
+
#input is a hash containing objects potentially needed. See modinput in ZiK.rb (main.rb) file.
|
203
|
+
end
|
204
|
+
|
205
|
+
def load
|
206
|
+
#Call when ZiK need to activate the module. Do not forget to set @loaded to true if module activation goes ok.
|
207
|
+
unless @loaded
|
208
|
+
ModErrorInfo.new(self, "Module loaded.")
|
209
|
+
@loaded=true
|
210
|
+
else
|
211
|
+
false
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def unload
|
216
|
+
#Call when ZiK need to deactivate the module. Do not forget to set @loaded to false.
|
217
|
+
if @loaded
|
218
|
+
ModErrorInfo.new(self, "Module unloaded.")
|
219
|
+
@loaded=false
|
220
|
+
true
|
221
|
+
else
|
222
|
+
false
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def configwidget
|
227
|
+
#Return a Gtk::Widget used in ZiK preferences windows in order to configure module (or nil).
|
228
|
+
nil
|
229
|
+
end
|
230
|
+
|
231
|
+
def saveconfig
|
232
|
+
#Called when configuration should be modified.
|
233
|
+
#If you writes a configuration file check first for the $write_config variable.
|
234
|
+
end
|
235
|
+
|
236
|
+
def quit
|
237
|
+
#Called when ZiK exits.
|
238
|
+
end
|
239
|
+
end
|
data/gui/preference.rb
ADDED
@@ -0,0 +1,496 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
Copyright 2007-2011 Vincent Carmona
|
4
|
+
vinc4mai@gmail.com
|
5
|
+
|
6
|
+
This file is part of ZiK.
|
7
|
+
|
8
|
+
ZiK is free software; you can redistribute it and/or modify
|
9
|
+
it under the terms of the GNU General Public License as published by
|
10
|
+
the Free Software Foundation; either version 2 of the License, or
|
11
|
+
(at your option) any later version.
|
12
|
+
|
13
|
+
ZiK is distributed in the hope that it will be useful,
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
GNU General Public License for more details.
|
17
|
+
|
18
|
+
You should have received a copy of the GNU General Public License
|
19
|
+
along with ZiK; if not, write to the Free Software
|
20
|
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
+
=end
|
22
|
+
|
23
|
+
class DirBox < Gtk::Frame
|
24
|
+
include Pack
|
25
|
+
|
26
|
+
def initialize(parent)
|
27
|
+
@parent=parent
|
28
|
+
@label=Gtk::Label.new
|
29
|
+
@label.wrap=true
|
30
|
+
@vbox=Gtk::VBox.new
|
31
|
+
@badd=Gtk::Button.new
|
32
|
+
@badd.image=Gtk::Image.new(Gtk::Stock::ADD,Gtk::IconSize::BUTTON)
|
33
|
+
@badd.tooltip_text=_('Add a directory.')
|
34
|
+
@badd.signal_connect('clicked'){add_directory_dialog}
|
35
|
+
super(_("Directories"))
|
36
|
+
border_width=$border
|
37
|
+
add(vpack([@label, @vbox, @badd]))
|
38
|
+
end
|
39
|
+
|
40
|
+
def ilabel=(str)
|
41
|
+
@label.label=str
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_directory(dir)
|
45
|
+
entry=Gtk::Entry.new
|
46
|
+
entry.text=dir
|
47
|
+
entry.editable=false
|
48
|
+
brm=Gtk::Button.new
|
49
|
+
brm.image=Gtk::Image.new(Gtk::Stock::REMOVE,Gtk::IconSize::BUTTON)
|
50
|
+
brm.tooltip_text=_('Delete this directory.')
|
51
|
+
pack=hpack([entry, brm])
|
52
|
+
@vbox.pack_start(pack, false)
|
53
|
+
pack.show_all
|
54
|
+
brm.signal_connect('clicked'){entry.destroy; brm.destroy; pack.destroy}
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_directory_dialog
|
58
|
+
dialog=Gtk::FileChooserDialog.new(_("Add a directory"), @parent,
|
59
|
+
Gtk::FileChooser::ACTION_SELECT_FOLDER, nil,
|
60
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
|
61
|
+
[Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
|
62
|
+
dialog.show_hidden=false
|
63
|
+
dialog.current_folder=ENV['HOME']
|
64
|
+
add_directory(dialog.filename) if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
|
65
|
+
dialog.destroy
|
66
|
+
end
|
67
|
+
|
68
|
+
def sdirectory
|
69
|
+
res=''
|
70
|
+
@vbox.children.each{|child| res+=child.children[0].text+','}
|
71
|
+
res
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class ExtBox < Gtk::Frame
|
76
|
+
include Pack
|
77
|
+
|
78
|
+
def initialize(config)
|
79
|
+
@nb=0
|
80
|
+
@label=Gtk::Label.new
|
81
|
+
@label.wrap=true
|
82
|
+
@table=Gtk::Table.new(1,3)
|
83
|
+
@table.column_spacings=$border
|
84
|
+
@table.row_spacings=$border
|
85
|
+
@bdefault=Gtk::Button.new(_('Default'))
|
86
|
+
@bdefault.tooltip_text=_('Reset to default.')
|
87
|
+
@bdefault.signal_connect('clicked'){
|
88
|
+
@table.children.each{|child| child.destroy}
|
89
|
+
@nb=0
|
90
|
+
config.default['extension'].split(',').each{|ext| add_ext(ext)}
|
91
|
+
}
|
92
|
+
@badd=Gtk::Button.new
|
93
|
+
@badd.image=Gtk::Image.new(Gtk::Stock::ADD,Gtk::IconSize::BUTTON)
|
94
|
+
@badd.tooltip_text=_('Add an extension.')
|
95
|
+
@badd.signal_connect('clicked'){add_ext}
|
96
|
+
super(_("Extensions"))
|
97
|
+
border_width=$border
|
98
|
+
add(vpack([@label, @table, hpack([@bdefault, @badd])]))
|
99
|
+
end
|
100
|
+
|
101
|
+
def ilabel=(str)
|
102
|
+
@label.label=str
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_ext(ext='')
|
106
|
+
entry=Gtk::Entry.new
|
107
|
+
entry.text=ext
|
108
|
+
entry.show
|
109
|
+
brm=Gtk::Button.new
|
110
|
+
brm.image=Gtk::Image.new(Gtk::Stock::REMOVE,Gtk::IconSize::BUTTON)
|
111
|
+
brm.tooltip_text=_('Delete this directory.')
|
112
|
+
brm.show
|
113
|
+
brm.signal_connect('clicked'){entry.destroy; brm.destroy; @nb-=1; refresh}
|
114
|
+
@table.attach(entry, @nb.modulo(3)*3, @nb.modulo(3)*3+1, @nb/3, @nb/3+1, Gtk::SHRINK, Gtk::SHRINK)
|
115
|
+
@table.attach(brm, @nb.modulo(3)*3+1, @nb.modulo(3)*3+2, @nb/3, @nb/3+1, Gtk::SHRINK, Gtk::SHRINK)
|
116
|
+
@nb+=1
|
117
|
+
end
|
118
|
+
|
119
|
+
def refresh
|
120
|
+
exts=[]
|
121
|
+
@table.children.reverse.each{|child|
|
122
|
+
exts.push(child.text) if child.is_a?(Gtk::Entry)
|
123
|
+
child.destroy
|
124
|
+
}
|
125
|
+
@nb=0
|
126
|
+
exts.each{|ext| add_ext(ext) unless ext.empty?}
|
127
|
+
end
|
128
|
+
|
129
|
+
def sext
|
130
|
+
res=''
|
131
|
+
@table.children.reverse_each{|child| res+=child.text+',' if child.is_a?(Gtk::Entry)}
|
132
|
+
res
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class FormatCombo < Gtk::ComboBox
|
137
|
+
def initialize
|
138
|
+
super()
|
139
|
+
self.append_text(_('None'))
|
140
|
+
self.append_text(_('Title'))
|
141
|
+
self.append_text(_('Artist'))
|
142
|
+
self.append_text(_('Album'))
|
143
|
+
self.append_text(_('Track'))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class FormatSelector < Gtk::HBox
|
148
|
+
def initialize(format)
|
149
|
+
@c1=FormatCombo.new
|
150
|
+
@c2=FormatCombo.new
|
151
|
+
@c3=FormatCombo.new
|
152
|
+
@c4=FormatCombo.new
|
153
|
+
self.format=format
|
154
|
+
super()
|
155
|
+
self.spacing=$border
|
156
|
+
[@c1, @c2, @c3, @c4].each{|c| self.pack_start(c, false)}
|
157
|
+
end
|
158
|
+
|
159
|
+
def format
|
160
|
+
retrieve(@c1)+' - '+retrieve(@c2)+' - '+retrieve(@c3)+' - '+retrieve(@c4)
|
161
|
+
end
|
162
|
+
|
163
|
+
def format=(format)
|
164
|
+
f=format.split(' - ')
|
165
|
+
select(@c1, f[0]);select(@c2, f[1]);select(@c3, f[2]);select(@c4, f[3])
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
|
170
|
+
def retrieve(combo)
|
171
|
+
case combo.active
|
172
|
+
when 0 then 'None'
|
173
|
+
when 1 then 'Title'
|
174
|
+
when 2 then 'Artist'
|
175
|
+
when 3 then 'Album'
|
176
|
+
when 4 then 'Track'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def select(combo, string)
|
181
|
+
case string
|
182
|
+
when 'None' then combo.active=0
|
183
|
+
when 'Title' then combo.active=1
|
184
|
+
when 'Artist' then combo.active=2
|
185
|
+
when 'Album' then combo.active=3
|
186
|
+
when 'Track' then combo.active=4
|
187
|
+
else
|
188
|
+
ErrorError.new("Parsing format (FomatSelector::select).")
|
189
|
+
combo.active=0
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
class Preference_window < Gtk::Window
|
195
|
+
include Pack
|
196
|
+
@@exist=false
|
197
|
+
|
198
|
+
def Preference_window.show(parent, playlist, config, page=:default, cdlist=nil, cdplayer=nil, cdgui=nil)
|
199
|
+
pages={:default=>0, :browse=>0, :playlist=>1, :player=>2, :cd=>3}
|
200
|
+
if @@exist
|
201
|
+
@@window.hide; @@window.show
|
202
|
+
else
|
203
|
+
@@window=Preference_window.new(parent,playlist,config, cdlist, cdplayer, cdgui)
|
204
|
+
end
|
205
|
+
@@window.page=pages[page]
|
206
|
+
end
|
207
|
+
|
208
|
+
def page=(n)
|
209
|
+
begin
|
210
|
+
@notebook.page=n
|
211
|
+
rescue
|
212
|
+
@notebook.page=0
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
def initialize(parent, playlist, config, cdlist, cdplayer, cdgui)
|
219
|
+
@@exist=true
|
220
|
+
|
221
|
+
#*********************Browser page******************************
|
222
|
+
#Directories
|
223
|
+
@dirbox=DirBox.new(self)
|
224
|
+
@dirbox.ilabel=_('List of directories displayed in the browser view.')
|
225
|
+
config['directory'].split(',').each{|dir| @dirbox.add_directory(dir)}
|
226
|
+
|
227
|
+
#Extensions
|
228
|
+
@extbox=ExtBox.new(config)
|
229
|
+
@extbox.ilabel=_('Only files with the given extension are displayed in the browser view. Extensions must be separate by a comma (,).')
|
230
|
+
config['extension'].split(',').each{|ext| @extbox.add_ext(ext)}
|
231
|
+
|
232
|
+
#Refresh on start
|
233
|
+
@brefresh=Gtk::CheckButton.new(_('Refresh browser view on start'))
|
234
|
+
@brefresh.active=config['refresh_on_start']
|
235
|
+
@refresh_label=Gtk::Label.new(_('Uncheck to use previous view (faster).'))
|
236
|
+
@refresh_label.wrap=true
|
237
|
+
@refresh_frame=Gtk::Frame.new
|
238
|
+
@refresh_frame.border_width=$border
|
239
|
+
@refresh_frame.add(vpack([@brefresh, @refresh_label]))
|
240
|
+
|
241
|
+
#Sort
|
242
|
+
@bsortdir=Gtk::CheckButton.new(_('Directories before files'))
|
243
|
+
@bsortdir.active=config['sort_directories_first']
|
244
|
+
@bsortcase=Gtk::CheckButton.new(_('Case sensitive'))
|
245
|
+
@bsortcase.active=config['sort_case_sensitive']
|
246
|
+
@sort_frame=Gtk::Frame.new(_('Sort options'))
|
247
|
+
@sort_frame.border_width=$border
|
248
|
+
@sort_frame.add(vpack([@bsortdir, @bsortcase]))
|
249
|
+
|
250
|
+
#Search
|
251
|
+
@bpath=Gtk::CheckButton.new(_('Path'))
|
252
|
+
@bpath.active=config['search_in_path']
|
253
|
+
@btitle=Gtk::CheckButton.new(_('Title'))
|
254
|
+
@btitle.active=config['search_in_title']
|
255
|
+
@bartist=Gtk::CheckButton.new(_('Artist'))
|
256
|
+
@bartist.active=config['search_in_artist']
|
257
|
+
@balbum=Gtk::CheckButton.new(_('Album'))
|
258
|
+
@balbum.active=config['search_in_album']
|
259
|
+
@bgenre=Gtk::CheckButton.new(_('Genre'))
|
260
|
+
@bgenre.active=config['search_in_genre']
|
261
|
+
@search_label=Gtk::Label.new(_('Check entries used for search. Use only path for speed.'))
|
262
|
+
@search_label.wrap=true
|
263
|
+
@search_table=Gtk::Table.new(4, 2)
|
264
|
+
@search_table.border_width=$border
|
265
|
+
@search_table.column_spacings=$border
|
266
|
+
@search_table.row_spacings=$border
|
267
|
+
@search_table.attach(@bpath, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL)
|
268
|
+
@search_table.attach(@btitle, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL)
|
269
|
+
@search_table.attach(@bartist, 1, 2, 1, 2, Gtk::FILL, Gtk::FILL)
|
270
|
+
@search_table.attach(@balbum, 0, 1, 2, 3, Gtk::FILL, Gtk::FILL)
|
271
|
+
@search_table.attach(@bgenre, 1, 2, 2, 3, Gtk::FILL, Gtk::FILL)
|
272
|
+
@search_table.attach(@search_label, 0, 2, 3, 4, Gtk::FILL, Gtk::FILL)
|
273
|
+
@search_frame=Gtk::Frame.new(_('Search'))
|
274
|
+
@search_frame.add(@search_table)
|
275
|
+
|
276
|
+
#Main box
|
277
|
+
@browser_box=vpack([@dirbox, @extbox, @refresh_frame, @sort_frame, @search_frame])
|
278
|
+
@wbrowser=Gtk::ScrolledWindow.new
|
279
|
+
@wbrowser.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
|
280
|
+
@wbrowser.add_with_viewport(@browser_box)
|
281
|
+
|
282
|
+
#*********************Playlist page*****************************
|
283
|
+
#session
|
284
|
+
@bsocket1=Gtk::RadioButton.new(_("Single"))
|
285
|
+
@bsocket2=Gtk::RadioButton.new(@bsocket1, _("Multi"))
|
286
|
+
config['socket'] ? @bsocket2.active=true : @bsocket1.active=true
|
287
|
+
|
288
|
+
@socket_frame=Gtk::Frame.new(_("Session"))
|
289
|
+
@socket_frame.border_width=$border
|
290
|
+
@socket_frame.add(hpack([@bsocket1, @bsocket2]))
|
291
|
+
#format
|
292
|
+
@format_selector=FormatSelector.new(config['name_format'])
|
293
|
+
@format_label=Gtk::Label.new(_('Format used to display songs\' name. Set all to None if you want to use file name.'))
|
294
|
+
@format_label.wrap=true
|
295
|
+
@format_frame=Gtk::Frame.new(_('Format'))
|
296
|
+
@format_frame.border_width=$border
|
297
|
+
@format_frame.add(vpack([@format_selector, @format_label]))
|
298
|
+
#color
|
299
|
+
@color_default=Gtk::Button.new(_('Default'))
|
300
|
+
@color_default.tooltip_text=_('Reset to default.')
|
301
|
+
@color_default.signal_connect('clicked'){@color_entry.text=config.default['playing_color']}
|
302
|
+
@color_entry=Gtk::Entry.new
|
303
|
+
@color_entry.text=config['playing_color']
|
304
|
+
@bcolor=Gtk::ColorButton.new(Gdk::Color.parse(config['playing_color']))
|
305
|
+
@bcolor.tooltip_text=_('Select a color.')
|
306
|
+
@bcolor.signal_connect('color-set'){@color_entry.text=@bcolor.color.to_s}
|
307
|
+
@color_label=Gtk::Label.new(_('Color used to highlight the current song.'))
|
308
|
+
@color_label.wrap=true
|
309
|
+
@color_frame=Gtk::Frame.new(_('Color'))
|
310
|
+
@color_frame.border_width=$border
|
311
|
+
@color_frame.add(vpack([hpack([@color_default, @color_entry, @bcolor]), @color_label]))
|
312
|
+
#compact
|
313
|
+
@bcompact=Gtk::CheckButton.new(_('Compact view'))
|
314
|
+
@bcompact.active=config['compact']
|
315
|
+
@compact_label=Gtk::Label.new(_('Show more tracks in playlist.'))
|
316
|
+
@compact_label.wrap=true
|
317
|
+
@compact_frame=Gtk::Frame.new(_('Compact view'))
|
318
|
+
@compact_frame.border_width=$border
|
319
|
+
@compact_frame.add(vpack([@bcompact, @compact_label]))
|
320
|
+
#sort
|
321
|
+
@bsorttrack=Gtk::CheckButton.new(_('Sort by track'))
|
322
|
+
@bsorttrack.active=config['sort_by_track']
|
323
|
+
@sort2_label=Gtk::Label.new(_('Try to sort files by track numbers when adding a directory.'))
|
324
|
+
@sort2_label.wrap=true
|
325
|
+
@sort2_frame=Gtk::Frame.new(_('Sort options'))
|
326
|
+
@sort2_frame.border_width=$border
|
327
|
+
@sort2_frame.add(vpack([@bsorttrack, @sort2_label]))
|
328
|
+
#relative
|
329
|
+
@brelative=Gtk::CheckButton.new(_('Relative paths'))
|
330
|
+
@brelative.active=config['relative_playlist']
|
331
|
+
@relative_label=Gtk::Label.new(_('Use relative paths when saving playlist.'))
|
332
|
+
@relative_label.wrap=true
|
333
|
+
@relative_frame=Gtk::Frame.new(_('Relative path'))
|
334
|
+
@relative_frame.border_width=$border
|
335
|
+
@relative_frame.add(vpack([@brelative, @relative_label]))
|
336
|
+
|
337
|
+
#main
|
338
|
+
@playlist_box=vpack([@socket_frame, @format_frame, @color_frame, @compact_frame,
|
339
|
+
@sort2_frame, @relative_frame])
|
340
|
+
|
341
|
+
#*********************Player page*******************************
|
342
|
+
@bplay=Gtk::CheckButton.new(_('Play on start'))
|
343
|
+
@bplay.image=Gtk::Image.new(Gtk::Stock::MEDIA_PLAY, Gtk::IconSize::BUTTON)
|
344
|
+
@bplay.active=config['play_on_start']
|
345
|
+
|
346
|
+
@bshuffle=Gtk::CheckButton.new(_('Shuffle'))
|
347
|
+
@bshuffle.image=Gtk::Image.new('media-playlist-shuffle', Gtk::IconSize::BUTTON)
|
348
|
+
@bshuffle.active=config['shuffle']
|
349
|
+
|
350
|
+
@brepeat=Gtk::CheckButton.new(_('Repeat'))
|
351
|
+
@brepeat.image=Gtk::Image.new('media-playlist-repeat', Gtk::IconSize::BUTTON)
|
352
|
+
@brepeat.active=config['repeat']
|
353
|
+
|
354
|
+
@player_box=vpack([@bplay, @bshuffle, @brepeat])
|
355
|
+
|
356
|
+
#*********************cd page***********************************
|
357
|
+
@device_default=Gtk::Button.new(_('Default'))
|
358
|
+
@device_default.tooltip_text=_('Reset to default.')
|
359
|
+
@device_default.signal_connect('clicked'){@device_entry.text=config.default['cd_device']}
|
360
|
+
@device_entry=Gtk::Entry.new
|
361
|
+
@device_entry.text=config['cd_device']
|
362
|
+
@device_frame=Gtk::Frame.new(_('Device'))
|
363
|
+
@device_frame.border_width=$border
|
364
|
+
@device_frame.add(vpack([hpack([@device_default, @device_entry])]))
|
365
|
+
|
366
|
+
@bweb=Gtk::CheckButton.new(_('Search for the songs'' title on the web.'))
|
367
|
+
@bweb.image=Gtk::Image.new(Gtk::Stock::NETWORK, Gtk::IconSize::BUTTON)
|
368
|
+
@bweb.active=config['cd_web']
|
369
|
+
|
370
|
+
@cd_box=vpack([@device_frame, @bweb])
|
371
|
+
|
372
|
+
#*********************Module page******************************
|
373
|
+
if $module
|
374
|
+
@module_frames=[]
|
375
|
+
@module_hbuttons={}
|
376
|
+
Mod.all.each{|m|
|
377
|
+
button=Gtk::CheckButton.new(m.title)
|
378
|
+
button.active=m.loaded?
|
379
|
+
@module_hbuttons[m.id]=button#Store check button
|
380
|
+
label=Gtk::Label.new(m.description)
|
381
|
+
label.wrap=true
|
382
|
+
widget=m.configwidget
|
383
|
+
frame=Gtk::Frame.new
|
384
|
+
frame.border_width=$border
|
385
|
+
@module_frames.push(frame)
|
386
|
+
if widget
|
387
|
+
expander=Gtk::Expander.new(_("Configuration"))
|
388
|
+
expander.spacing=$border
|
389
|
+
expander.add(widget)
|
390
|
+
frame.add(vpack([button, label, expander]))
|
391
|
+
else
|
392
|
+
frame.add(vpack([button, label]))
|
393
|
+
end
|
394
|
+
}
|
395
|
+
@module_box=vpack(@module_frames)
|
396
|
+
@wmodule=Gtk::ScrolledWindow.new
|
397
|
+
@wmodule.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
|
398
|
+
@wmodule.add_with_viewport(@module_box)
|
399
|
+
end
|
400
|
+
|
401
|
+
#*********************Main window*******************************
|
402
|
+
@notebook=Gtk::Notebook.new
|
403
|
+
@notebook.tab_pos=Gtk::POS_LEFT
|
404
|
+
@notebook.append_page(@wbrowser, Gtk::Label.new(_('Browser')))
|
405
|
+
@notebook.append_page(@playlist_box, Gtk::Label.new(_('Playlist')))
|
406
|
+
@notebook.append_page(@player_box, Gtk::Label.new(_('Player')))
|
407
|
+
@notebook.append_page(@cd_box, Gtk::Label.new(_('Cd')))
|
408
|
+
@notebook.append_page(@wmodule, Gtk::Label.new(_('Modules'))) if $module
|
409
|
+
|
410
|
+
@bcancel=Gtk::Button.new(Gtk::Stock::CANCEL)
|
411
|
+
@bcancel.signal_connect('clicked'){quit}
|
412
|
+
@bok=Gtk::Button.new(Gtk::Stock::OK)
|
413
|
+
@bok.signal_connect('clicked'){
|
414
|
+
oldconfig={}; oldconfig.merge!(config)
|
415
|
+
config.merge!({'directory'=>@dirbox.sdirectory, 'extension'=>@extbox.sext,
|
416
|
+
'sort_directories_first'=>@bsortdir.active?, 'sort_case_sensitive'=>@bsortcase.active?, 'refresh_on_start'=>@brefresh.active?,
|
417
|
+
'search_in_path'=>@bpath.active?, 'search_in_title'=>@btitle.active?,
|
418
|
+
'search_in_artist'=>@bartist.active?, 'search_in_album'=>@balbum.active?, 'search_in_genre'=>@bgenre.active?,
|
419
|
+
'socket'=>@bsocket2.active?,
|
420
|
+
'name_format'=>@format_selector.format, 'relative_playlist'=>@brelative.active?,
|
421
|
+
'compact'=>@bcompact.active?,
|
422
|
+
'sort_by_track'=>@bsorttrack.active?, 'playing_color'=>@color_entry.text,
|
423
|
+
'play_on_start'=>@bplay.active?, 'shuffle'=>@bshuffle.active?, 'repeat'=>@brepeat.active?,
|
424
|
+
'cd_device'=>@device_entry.text, 'cd_web'=>@bweb.active?})
|
425
|
+
if $module
|
426
|
+
config['module']=''
|
427
|
+
@module_hbuttons.each_pair{|key, value| config['module']+=key+',' if value.active?}
|
428
|
+
end
|
429
|
+
begin
|
430
|
+
Gdk::Color.parse(config['playing_color'])
|
431
|
+
rescue
|
432
|
+
ErrorError.new("#{config['playing_color']} is not a color. Restore previous color.")
|
433
|
+
config['playing_color']=oldconfig['playing_color']
|
434
|
+
end
|
435
|
+
unless oldconfig['name_format']==config['name_format']
|
436
|
+
playlist.songs.each{|song| song.refresh_name(config['name_format'])}
|
437
|
+
parent.refresh_liststore
|
438
|
+
end
|
439
|
+
parent.compact(config['compact']) unless oldconfig['compact']==config['compact']
|
440
|
+
playlist.sort_by_track=config['sort_by_track']
|
441
|
+
noc=(oldconfig['directory']==config['directory'] and oldconfig['extension']==config['extension'] and
|
442
|
+
oldconfig['sort_directories_first']==config['sort_directories_first'] and
|
443
|
+
oldconfig['sort_case_sensitive']==config['sort_case_sensitive'])
|
444
|
+
unless noc
|
445
|
+
parent.refresh_treestore(config['directory'],config['extension'])
|
446
|
+
end
|
447
|
+
unless config['playing_color']==oldconfig['playing_color']
|
448
|
+
parent.renderer2.background=config['playing_color']
|
449
|
+
cdgui.renderer.background=config['playing_color'] if $cd
|
450
|
+
end
|
451
|
+
parent.shuffle=config['shuffle']
|
452
|
+
parent.repeat=config['repeat']
|
453
|
+
if $cd
|
454
|
+
cdlist.web=config['cd_web']
|
455
|
+
unless oldconfig['cd_device']==config['cd_device']
|
456
|
+
cdplayer.device=config['cd_device']
|
457
|
+
cdlist.device=config['cd_device']
|
458
|
+
cdlist.refresh
|
459
|
+
cdgui.refresh_store
|
460
|
+
end
|
461
|
+
end
|
462
|
+
if $module
|
463
|
+
Mod.all.each{|mod| mod.saveconfig}
|
464
|
+
Mod.all.each{|mod|
|
465
|
+
config['module'].split(',').include?(mod.id) ? mod.load : mod.unload
|
466
|
+
ModErrorLoadError.show_all
|
467
|
+
} unless config['module']==oldconfig['module']
|
468
|
+
end
|
469
|
+
quit
|
470
|
+
}
|
471
|
+
@hbox=Gtk::HBox.new
|
472
|
+
[@bcancel, @bok].reverse.each{|button| @hbox.pack_end(button,false)}
|
473
|
+
|
474
|
+
@vbox=Gtk::VBox.new
|
475
|
+
@vbox.pack_start(@notebook)
|
476
|
+
@vbox.pack_start(@hbox,false)
|
477
|
+
|
478
|
+
super(Gtk::Window::TOPLEVEL)
|
479
|
+
self.transient_for=parent
|
480
|
+
self.skip_taskbar_hint=true
|
481
|
+
self.skip_pager_hint=true
|
482
|
+
self.title=_('Preferences')
|
483
|
+
self.icon=Gdk::Pixbuf.new(File.join(Pix_dir,'ZiK.svg'))
|
484
|
+
|
485
|
+
self.signal_connect("delete_event") {quit;true}
|
486
|
+
|
487
|
+
self.add(@vbox)
|
488
|
+
|
489
|
+
self.show_all
|
490
|
+
end
|
491
|
+
|
492
|
+
def quit
|
493
|
+
@@exist=false
|
494
|
+
self.destroy
|
495
|
+
end
|
496
|
+
end
|