zik 0.16.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.
- 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
|