XDCC-Fetch 1.386 → 1.409
Sign up to get free protection for your applications and to get access to all the features.
- data/XDCC-Fetch.rbw +17 -16
- data/doc/index.html +12 -1
- data/doc/xdccfetch.css +6 -1
- data/icons/locale.png +0 -0
- data/src/GUI/Application_Builder.rb +25 -9
- data/src/GUI/Context_Menu.rb +33 -9
- data/src/GUI/Download_Finished_Box.rb +13 -10
- data/src/GUI/Empty_Text_Field_Handler.rb +2 -1
- data/src/GUI/Gui_Logic.rb +36 -99
- data/src/GUI/Main_Window.rb +60 -16
- data/src/GUI/Packet_Item.rb +36 -1
- data/src/GUI/Packet_List.rb +47 -2
- data/src/GUI/Search_Engine.rb +187 -0
- data/src/GUI/Talk_Back.rb +1 -2
- data/src/GUI/Toggle_Button.rb +1 -1
- data/src/Network/DCC_File.rb +54 -44
- data/src/Network/TCP_Connection.rb +6 -5
- data/src/Network/XDCC_Download_Handler.rb +5 -1
- data/src/Translations/check_translations +5 -5
- data/src/Translations/de.rb +3 -1
- data/src/Translations/en.rb +5 -1
- data/src/Translations/pl.rb +145 -0
- data/src/Utilities/Configuration.rb +1 -1
- data/src/Utilities/Globals.rb +7 -3
- data/src/Utilities/Recursive_Open_Struct.rb +110 -11
- metadata +26 -24
- data/src/Utilities/PrettyException.rb +0 -1091
data/XDCC-Fetch.rbw
CHANGED
@@ -6,14 +6,14 @@
|
|
6
6
|
# Redistribution and use in source and binary forms, with or without modification,
|
7
7
|
# are permitted provided that the following conditions are met:
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
9
|
+
# * Redistributions of source code must retain the above copyright notice, this list
|
10
|
+
# of conditions and the following disclaimer.
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright notice, this list
|
12
|
+
# of conditions and the following disclaimer in the documentation and/or other materials
|
13
|
+
# provided with the distribution.
|
14
|
+
# * Neither the name of Christoph Heindl and Martin Ankerl nor the names of its contributors
|
15
|
+
# may be used to endorse or promote products derived from this software without specific
|
16
|
+
# prior written permission.
|
17
17
|
#
|
18
18
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
19
19
|
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
@@ -24,9 +24,10 @@
|
|
24
24
|
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
25
25
|
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
26
|
|
27
|
-
begin
|
27
|
+
#begin
|
28
28
|
Dir.chdir(File.dirname(File.expand_path(__FILE__)))
|
29
29
|
require 'src/GUI/Main_Window'
|
30
|
+
=begin
|
30
31
|
rescue Exception => err
|
31
32
|
outPath = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
|
32
33
|
logfile = nil
|
@@ -39,16 +40,16 @@ rescue Exception => err
|
|
39
40
|
logfile.puts("Encountered fatal error on #{Time.now}")
|
40
41
|
logfile.puts(err.message)
|
41
42
|
logfile.puts(err.backtrace)
|
43
|
+
logfile.puts("Ruby Version: #{RUBY_PLATFORM}, #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})")
|
44
|
+
logfile.puts("Reason: #{err.message}")
|
45
|
+
logfile.puts("Where: #{err.backtrace[0]}")
|
46
|
+
logfile.puts("Inspect: #{err.inspect}")
|
47
|
+
logfile.puts("Full Backtrace:")
|
48
|
+
logfile.puts(err.backtrace.map{|t| "\t#{t}\n"}.join)
|
42
49
|
logfile.puts("----------------------END--------------------------")
|
43
50
|
logfile.close
|
44
51
|
|
45
|
-
# use prettyexception. For internal use, or whoever wants to hack the source.
|
46
|
-
require 'src/Utilities/PrettyException'
|
47
|
-
pe = PrettyException.new(err)
|
48
|
-
File.open(outPath + "/.xdcc-fetch-prettylog.html", "w") do |f|
|
49
|
-
f.puts pe.print
|
50
|
-
end
|
51
|
-
|
52
52
|
#require 'src/GUI/Talk_Back'
|
53
53
|
#Talk_Back.run(err)
|
54
54
|
end
|
55
|
+
=end
|
data/doc/index.html
CHANGED
@@ -30,6 +30,9 @@
|
|
30
30
|
</div>
|
31
31
|
|
32
32
|
<div id="news">
|
33
|
+
<h1>2005-01-30</h1>
|
34
|
+
<p>XDCC-Fetch 1.386 Better error handling, faster search + sort</p>
|
35
|
+
|
33
36
|
<h1>2005-01-22</h1>
|
34
37
|
<p>XDCC-Fetch 1.338 New features, several bugfixes</p>
|
35
38
|
|
@@ -136,7 +139,7 @@
|
|
136
139
|
</tr>
|
137
140
|
</table>
|
138
141
|
|
139
|
-
<a name="download"></a><h1>Download</h1>
|
142
|
+
<a name="download"></a><h1>Download</h1>
|
140
143
|
<dl>
|
141
144
|
<dt>
|
142
145
|
<a href="http://sourceforge.net/project/showfiles.php?group_id=127145">XDCC-Fetch Release</a>
|
@@ -152,6 +155,14 @@
|
|
152
155
|
As the name says,the nightly is updated (almost) each night. Have a look at the
|
153
156
|
<a href="changelog.html">changelog</a> to find out if your favourite bug has been fixed.</dd>
|
154
157
|
</dl>
|
158
|
+
<p>
|
159
|
+
The XDCC-Fetch releases are also available as <a href="http://rubygems.rubyforge.org/wiki/wiki.pl?RubyGems">Ruby Gems</a>.
|
160
|
+
You can install it via this command:
|
161
|
+
</p>
|
162
|
+
<pre>gem install xdcc-fetch</pre>
|
163
|
+
<p>
|
164
|
+
After installation you can start XDCC-Fetch by executing <tt>XDCC-Fetch.rbw</tt>.
|
165
|
+
</p>
|
155
166
|
|
156
167
|
<a name="install"></a><h1>Installation</h1>
|
157
168
|
<p>
|
data/doc/xdccfetch.css
CHANGED
data/icons/locale.png
ADDED
Binary file
|
@@ -1,17 +1,17 @@
|
|
1
|
-
# Copyright (c) 2004
|
1
|
+
# Copyright (c) 2004-2005 Christoph Heindl and Martin Ankerl
|
2
2
|
# All rights reserved.
|
3
3
|
#
|
4
4
|
# Redistribution and use in source and binary forms, with or without modification,
|
5
5
|
# are permitted provided that the following conditions are met:
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this list
|
8
|
+
# of conditions and the following disclaimer.
|
9
|
+
# * Redistributions in binary form must reproduce the above copyright notice, this list
|
10
|
+
# of conditions and the following disclaimer in the documentation and/or other materials
|
11
|
+
# provided with the distribution.
|
12
|
+
# * Neither the name of Christoph Heindl and Martin Ankerl nor the names of its contributors
|
13
|
+
# may be used to endorse or promote products derived from this software without specific
|
14
|
+
# prior written permission.
|
15
15
|
#
|
16
16
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
17
17
|
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
@@ -50,6 +50,22 @@ class Application_Builder
|
|
50
50
|
file.add_separator
|
51
51
|
file.add($cfg.text.quit, $cfg.icons.quit) { FXApp::instance.exit }
|
52
52
|
|
53
|
+
options = Context_Menu.new(menu_bar, $cfg.text.options)
|
54
|
+
|
55
|
+
# build languages
|
56
|
+
languages = Context_Menu.new(@gui.main_window)
|
57
|
+
lang_defs = Array.new
|
58
|
+
$cfg.translations.attrs.each do |lang|
|
59
|
+
lang_defs.push [$cfg.translations[lang].language_name, lang]
|
60
|
+
end
|
61
|
+
@gui.language_radios = Array.new
|
62
|
+
lang_defs.sort.each do |name, lang|
|
63
|
+
cmd = languages.add_radio(name, lang==$cfg.config.current_language) { |*args| @logic.on_language_change(lang, *args) }
|
64
|
+
@gui.language_radios.push cmd
|
65
|
+
end
|
66
|
+
options.add_submenu($cfg.text.language, languages, $cfg.icons.translations)
|
67
|
+
|
68
|
+
|
53
69
|
help = Context_Menu.new(menu_bar, $cfg.text.help)
|
54
70
|
help.add($cfg.text.about, $cfg.icons.about) { @logic.on_about_click }
|
55
71
|
end
|
data/src/GUI/Context_Menu.rb
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without modification,
|
5
5
|
# are permitted provided that the following conditions are met:
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this list
|
8
|
+
# of conditions and the following disclaimer.
|
9
|
+
# * Redistributions in binary form must reproduce the above copyright notice, this list
|
10
|
+
# of conditions and the following disclaimer in the documentation and/or other materials
|
11
|
+
# provided with the distribution.
|
12
|
+
# * Neither the name of Martin Ankerl nor the names of its contributors may be used to
|
13
|
+
# endorse or promote products derived from this software without specific prior written
|
14
|
+
# permission.
|
15
15
|
#
|
16
16
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
17
17
|
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
@@ -24,7 +24,7 @@
|
|
24
24
|
|
25
25
|
# Context_Menu is a more convenient way to use context menus. It allows the creation of states that enable/disable items.
|
26
26
|
class Context_Menu
|
27
|
-
attr_accessor :data
|
27
|
+
attr_accessor :data, :pane
|
28
28
|
|
29
29
|
# Creates a new Context_Menu for given parent. If you provide a block,
|
30
30
|
# this code is called whenever the menu is shown.
|
@@ -56,6 +56,30 @@ class Context_Menu
|
|
56
56
|
cmd
|
57
57
|
end
|
58
58
|
|
59
|
+
def add_check(text, checked=false, icon=nil, &proc)
|
60
|
+
cmd = FXMenuCheck.new(@pane, text, icon)
|
61
|
+
@menu_commands.push cmd
|
62
|
+
cmd.check = checked
|
63
|
+
cmd.connect(SEL_COMMAND) { |sender, sel, data| proc.call(self, sender, sel, data) }
|
64
|
+
@pane.recalc
|
65
|
+
cmd
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_radio(text, checked=false, icon=nil, &proc)
|
69
|
+
cmd = FXMenuRadio.new(@pane, text, icon)
|
70
|
+
@menu_commands.push cmd
|
71
|
+
cmd.check = checked
|
72
|
+
cmd.connect(SEL_COMMAND) { |sender, sel, data| proc.call(self, sender, sel, data) }
|
73
|
+
@pane.recalc
|
74
|
+
cmd
|
75
|
+
end
|
76
|
+
|
77
|
+
# adds a subcontextmenu
|
78
|
+
def add_submenu(text, menu, icon=nil)
|
79
|
+
FXMenuCascade.new(@pane, text, icon, menu.pane)
|
80
|
+
end
|
81
|
+
|
82
|
+
|
59
83
|
# Create a new state which can later be accessed using the key state_name.
|
60
84
|
# For each menu entry, you need to specify if it should be enabled or disabled (true/false).
|
61
85
|
def new_state(state_name, *args)
|
@@ -1,17 +1,20 @@
|
|
1
|
-
#
|
2
|
-
#
|
1
|
+
# Authors:: Martin Ankerl (mailto:martin.ankerl@gmail.com)\<br>
|
2
|
+
# Christoph Heindl (mailto:christoph.heindl@gmail.com)
|
3
|
+
#
|
4
|
+
# Copyright:: Copyright (c) 2004-2005 Christoph Heindl, Martin Ankerl
|
5
|
+
# License:: XDCC-Fetch may be redistributed under the terms of the BSD licence:
|
3
6
|
#
|
4
7
|
# Redistribution and use in source and binary forms, with or without modification,
|
5
8
|
# are permitted provided that the following conditions are met:
|
6
9
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
10
|
+
# * Redistributions of source code must retain the above copyright notice, this list
|
11
|
+
# of conditions and the following disclaimer.
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright notice, this list
|
13
|
+
# of conditions and the following disclaimer in the documentation and/or other materials
|
14
|
+
# provided with the distribution.
|
15
|
+
# * Neither the name of Christoph Heindl and Martin Ankerl nor the names of its contributors
|
16
|
+
# may be used to endorse or promote products derived from this software without specific
|
17
|
+
# prior written permission.
|
15
18
|
#
|
16
19
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
17
20
|
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
@@ -22,6 +22,7 @@
|
|
22
22
|
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
23
23
|
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
24
24
|
|
25
|
+
|
25
26
|
# Shows a grey text in an FXTextField if the user did not enter any input. This is a nice way to
|
26
27
|
# give the user more information about what to enter into a text field, without the need of additional
|
27
28
|
# space in the GUI.
|
@@ -83,4 +84,4 @@ class Empty_Text_Field_Handler
|
|
83
84
|
@textField.text = @myText
|
84
85
|
@isEmpty = true
|
85
86
|
end
|
86
|
-
end
|
87
|
+
end
|
data/src/GUI/Gui_Logic.rb
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# Redistribution and use in source and binary forms, with or without modification,
|
5
5
|
# are permitted provided that the following conditions are met:
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this list
|
8
|
+
# of conditions and the following disclaimer.
|
9
|
+
# * Redistributions in binary form must reproduce the above copyright notice, this list
|
10
|
+
# of conditions and the following disclaimer in the documentation and/or other materials
|
11
|
+
# provided with the distribution.
|
12
|
+
# * Neither the name of Martin Ankerl nor the names of its contributors may be used to
|
13
|
+
# endorse or promote products derived from this software without specific prior written
|
14
|
+
# permission.
|
15
15
|
#
|
16
16
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
17
17
|
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
@@ -35,6 +35,19 @@ class Gui_Logic
|
|
35
35
|
def initialize(gui, data)
|
36
36
|
@gui = gui
|
37
37
|
@data = data
|
38
|
+
@search_engine = Search_Engine.new(@gui, @data)
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_search
|
42
|
+
@search_engine.on_search
|
43
|
+
end
|
44
|
+
|
45
|
+
def match?(*args)
|
46
|
+
@search_engine.match?(*args)
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_search_status_text
|
50
|
+
@search_engine.update_search_status_text
|
38
51
|
end
|
39
52
|
|
40
53
|
# Adds a new IRC_server and connects to it.
|
@@ -126,93 +139,6 @@ class Gui_Logic
|
|
126
139
|
x
|
127
140
|
end
|
128
141
|
|
129
|
-
# Update the text for the number of displayed packs.
|
130
|
-
def update_search_status_text
|
131
|
-
@gui.search_status_label.text = " #{@gui.packet_list.numItems} #{$cfg.text.of} #{@data.allpack_to_item.size} #{$cfg.text.packs}"
|
132
|
-
end
|
133
|
-
|
134
|
-
# Find out if item is matched by current search criteria.
|
135
|
-
def match?(item, match_data)
|
136
|
-
# check icon
|
137
|
-
return false unless @data.packet_icon_to_toggle_btn[item.icon].toggled?
|
138
|
-
|
139
|
-
# check text
|
140
|
-
return true if match_data.empty?
|
141
|
-
item_str = item.sortable(1)
|
142
|
-
match_data.each do |match_str|
|
143
|
-
if match_str[0] == ?-
|
144
|
-
# the next items are not allowed to be contained in pack name
|
145
|
-
return false if (match_str[1..-1]!="") && (item_str.include?(match_str[1..-1]))
|
146
|
-
else
|
147
|
-
return false if !item_str.include?(match_str)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
true
|
151
|
-
end
|
152
|
-
|
153
|
-
# Executed whenever a search criteria changes to update the packet list.
|
154
|
-
def on_search
|
155
|
-
# restart current search
|
156
|
-
# TODO what happens when new announcements come every 0.2 second or so?
|
157
|
-
# the list will never be updated... :-/
|
158
|
-
@end_time = Time.now + 0.5
|
159
|
-
@restart_search = true
|
160
|
-
@gui.search_label.enabled = false
|
161
|
-
return if @search_thread && @search_thread.status
|
162
|
-
|
163
|
-
@search_thread = Thread.new(@search_thread) do
|
164
|
-
begin
|
165
|
-
@gui.search_label.enabled = false
|
166
|
-
# wait untill deadline
|
167
|
-
while (t = (@end_time - Time.now)) > 0
|
168
|
-
sleep(t)
|
169
|
-
end
|
170
|
-
|
171
|
-
@data.gui_mutex.synchronize do
|
172
|
-
# the thread has to use the gui mutex inside
|
173
|
-
@restart_search = false
|
174
|
-
|
175
|
-
@match_data = @gui.search_field.text.downcase.split
|
176
|
-
|
177
|
-
# remove all items
|
178
|
-
@gui.packet_list.dirty_clear
|
179
|
-
|
180
|
-
# add all items that match the search criteria
|
181
|
-
sort_deadline = Time.now
|
182
|
-
status_text_deadline = Time.now
|
183
|
-
@data.allpack_to_item.each_value do |item|
|
184
|
-
#item.parent = @gui.packet_list if match?(item, match_data)
|
185
|
-
if match?(item, @match_data)
|
186
|
-
item.show
|
187
|
-
|
188
|
-
# take only about 10% of the cpu to sort items.
|
189
|
-
# with few items this results to very fast sorts,
|
190
|
-
# with many items this leads to fast updates.
|
191
|
-
if (sort_deadline < Time.now)
|
192
|
-
before = Time.now
|
193
|
-
@gui.packet_list.sortItems
|
194
|
-
after = Time.now
|
195
|
-
sort_deadline = after + (after-before) *10
|
196
|
-
end
|
197
|
-
|
198
|
-
# update every 0.1 second
|
199
|
-
if (status_text_deadline < Time.now)
|
200
|
-
update_search_status_text
|
201
|
-
status_text_deadline = Time.now + 0.1
|
202
|
-
end
|
203
|
-
end
|
204
|
-
break if @restart_search
|
205
|
-
end
|
206
|
-
update_search_status_text
|
207
|
-
@gui.packet_list.sortItems
|
208
|
-
@gui.search_label.enabled = true
|
209
|
-
|
210
|
-
FXApp::instance.flush
|
211
|
-
end # synchronize
|
212
|
-
end while @restart_search# || @match_data != @gui.search_field.text.downcase.split
|
213
|
-
end #thread.new
|
214
|
-
end
|
215
|
-
|
216
142
|
def add_server(ip, port, nick, pwd, do_connect)
|
217
143
|
name = "#{ip}"
|
218
144
|
server_item = @gui.connections.addItemLast(nil, name, $cfg.icons.disconnected, $cfg.icons.disconnected)
|
@@ -349,6 +275,16 @@ class Gui_Logic
|
|
349
275
|
About_Dialog.new(@gui.main_window).execute
|
350
276
|
end
|
351
277
|
|
278
|
+
# change configured language
|
279
|
+
def on_language_change(lang, menu, sender, sel, data)
|
280
|
+
@gui.language_radios.each do |radio|
|
281
|
+
radio.check = false unless radio == sender
|
282
|
+
end
|
283
|
+
# update config
|
284
|
+
$cfg.config.current_language = lang
|
285
|
+
@data.config.save
|
286
|
+
end
|
287
|
+
|
352
288
|
|
353
289
|
# Let user select a target directory and initiate download if user clicks OK.
|
354
290
|
def on_download_click(menu, sender, sel, data)
|
@@ -497,7 +433,7 @@ class Gui_Logic
|
|
497
433
|
end
|
498
434
|
|
499
435
|
is_added = false
|
500
|
-
match_data = @
|
436
|
+
match_data = @search_engine.get_match_data
|
501
437
|
ann.packs.each do |pack|
|
502
438
|
# create an unconnected item
|
503
439
|
item = Packet_Item.new(nil, icon, bot, pack.name, pack.size)
|
@@ -515,7 +451,6 @@ class Gui_Logic
|
|
515
451
|
update_search_status_text
|
516
452
|
@gui.packet_list.sortItems
|
517
453
|
end
|
518
|
-
#on_search
|
519
454
|
|
520
455
|
when XDCC_Announcement_Storage::ON_ANNOUNCEMENT_LOST
|
521
456
|
ann = args[0]
|
@@ -620,8 +555,10 @@ class Gui_Logic
|
|
620
555
|
if irc_user == caller.me
|
621
556
|
server_item = @data.irc_server_to_item[caller]
|
622
557
|
channel_item = @data.server_to_channels[server_item].detect { |channel_item| channel_item.text == channel_name }
|
623
|
-
channel_item
|
624
|
-
|
558
|
+
if channel_item
|
559
|
+
channel_item.closedIcon = $cfg.icons.connection_failed
|
560
|
+
channel_item.openIcon = $cfg.icons.connection_failed
|
561
|
+
end
|
625
562
|
end
|
626
563
|
end
|
627
564
|
end
|