XDCC-Fetch 1.386
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/COPYING +23 -0
- data/XDCC-Fetch.rbw +54 -0
- data/doc/ark.png +0 -0
- data/doc/connect_established.png +0 -0
- data/doc/index.html +300 -0
- data/doc/mega_ark.png +0 -0
- data/doc/package.png +0 -0
- data/doc/package_unknown.png +0 -0
- data/doc/shot1.png +0 -0
- data/doc/shot1_mini.png +0 -0
- data/doc/shot2.png +0 -0
- data/doc/shot2_mini.png +0 -0
- data/doc/xdccfetch.css +155 -0
- data/icons/ark.png +0 -0
- data/icons/ark_big.png +0 -0
- data/icons/camera_test.png +0 -0
- data/icons/cancel.png +0 -0
- data/icons/connect_creating.png +0 -0
- data/icons/connect_established.png +0 -0
- data/icons/connect_failed.png +0 -0
- data/icons/connect_no.png +0 -0
- data/icons/edit_add.png +0 -0
- data/icons/edit_remove.png +0 -0
- data/icons/exit.png +0 -0
- data/icons/fileclose.png +0 -0
- data/icons/folder_inbox.png +0 -0
- data/icons/idea.png +0 -0
- data/icons/mega_ark.png +0 -0
- data/icons/messagebox_critical.png +0 -0
- data/icons/messagebox_info.png +0 -0
- data/icons/messagebox_warning.png +0 -0
- data/icons/messagebox_warning_small.png +0 -0
- data/icons/package.png +0 -0
- data/icons/package_favourite.png +0 -0
- data/icons/package_unknown.png +0 -0
- data/src/Console/Console_Parser.rb +71 -0
- data/src/Console/XDCC_Pack_Match_Template.rb +29 -0
- data/src/Console/xdcc-fetch.rb +123 -0
- data/src/GUI/About_Dialog.rb +50 -0
- data/src/GUI/Application_Builder.rb +280 -0
- data/src/GUI/Context_Menu.rb +81 -0
- data/src/GUI/Custom_Tabs.rb +60 -0
- data/src/GUI/Dialog_Box.rb +116 -0
- data/src/GUI/Download_Finished_Box.rb +41 -0
- data/src/GUI/Empty_Text_Field_Handler.rb +86 -0
- data/src/GUI/Gui_Logic.rb +629 -0
- data/src/GUI/Icon_Loader.rb +58 -0
- data/src/GUI/Main_Window.rb +227 -0
- data/src/GUI/Packet_Item.rb +171 -0
- data/src/GUI/Packet_List.rb +145 -0
- data/src/GUI/Speed_Widget.rb +101 -0
- data/src/GUI/Talk_Back.rb +118 -0
- data/src/GUI/Toggle_Button.rb +56 -0
- data/src/Network/CTCP_Handler.rb +61 -0
- data/src/Network/DCC_File.rb +323 -0
- data/src/Network/DCC_Parser.rb +71 -0
- data/src/Network/IPAddr_Ext.rb +76 -0
- data/src/Network/IRC_Message.rb +161 -0
- data/src/Network/IRC_Server.rb +273 -0
- data/src/Network/IRC_Server_Respond_Map.rb +223 -0
- data/src/Network/IRC_User.rb +58 -0
- data/src/Network/TCP_Connection.rb +168 -0
- data/src/Network/XDCC_Announcement.rb +120 -0
- data/src/Network/XDCC_Announcement_Storage.rb +167 -0
- data/src/Network/XDCC_Download_Handler.rb +412 -0
- data/src/Network/XDCC_Pack.rb +58 -0
- data/src/Network/XDCC_Parser.rb +253 -0
- data/src/Translations/README +61 -0
- data/src/Translations/check_translations +83 -0
- data/src/Translations/de.rb +140 -0
- data/src/Translations/en.rb +145 -0
- data/src/Utilities/Configuration.rb +91 -0
- data/src/Utilities/Events.rb +87 -0
- data/src/Utilities/Globals.rb +138 -0
- data/src/Utilities/PrettyException.rb +1091 -0
- data/src/Utilities/Recursive_Open_Struct.rb +159 -0
- data/src/Utilities/Timer.rb +71 -0
- metadata +135 -0
data/icons/ark.png
ADDED
Binary file
|
data/icons/ark_big.png
ADDED
Binary file
|
Binary file
|
data/icons/cancel.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/icons/edit_add.png
ADDED
Binary file
|
Binary file
|
data/icons/exit.png
ADDED
Binary file
|
data/icons/fileclose.png
ADDED
Binary file
|
Binary file
|
data/icons/idea.png
ADDED
Binary file
|
data/icons/mega_ark.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/icons/package.png
ADDED
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Parses command line input and selects the appropriate action if any
|
2
|
+
class Console_Parser
|
3
|
+
def initialize
|
4
|
+
@commands = Hash.new
|
5
|
+
@commands["help"] = [0, "Prints this help", "Need help on help?",
|
6
|
+
proc do |parser, params|
|
7
|
+
puts ""
|
8
|
+
puts "COMMAND\t\t\tDESCRIPTION"
|
9
|
+
puts "------------------------------------"
|
10
|
+
parser.commands_each do |command, params|
|
11
|
+
puts "#{command}\t\t\t#{params[1] if params[1]}"
|
12
|
+
end
|
13
|
+
puts ""
|
14
|
+
end
|
15
|
+
]
|
16
|
+
@commands["details"] = [1, "Prints detail information on the given command", nil,
|
17
|
+
proc do |parser, params|
|
18
|
+
puts ""
|
19
|
+
puts "DETAILS"
|
20
|
+
puts "------------"
|
21
|
+
details = parser.get_details(params[0])
|
22
|
+
if details
|
23
|
+
puts "#{params[0]}:\r\n#{details}"
|
24
|
+
else
|
25
|
+
puts "#{params[0]}:\r\nNo detail help available"
|
26
|
+
end
|
27
|
+
puts ""
|
28
|
+
end
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_command(command, action, nrOfParameters, description=nil, details=nil)
|
33
|
+
@commands[command.downcase] ||= [nrOfParameters, description, details, action]
|
34
|
+
end
|
35
|
+
|
36
|
+
def remove_command(command)
|
37
|
+
@commands.delete[command.downcase]
|
38
|
+
end
|
39
|
+
|
40
|
+
def commands_each
|
41
|
+
@commands.each_pair do |key, value| yield key, value end
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_details(command)
|
45
|
+
nrOfParameters, description, details, action = @commands[command.downcase]
|
46
|
+
details
|
47
|
+
end
|
48
|
+
|
49
|
+
def call_command(str)
|
50
|
+
args = str.scan(/\S+/)
|
51
|
+
# Locate the given command
|
52
|
+
if !@commands.has_key?(args[0].downcase)
|
53
|
+
puts "Unknown command, type \"help\" for help"
|
54
|
+
else
|
55
|
+
nrOfParameters, description, details, action = @commands[args[0].downcase]
|
56
|
+
if nrOfParameters != args[1..-1].length
|
57
|
+
puts "Wrong number of arguments"
|
58
|
+
self.call_command("details #{args[0]} #{details}")
|
59
|
+
else
|
60
|
+
action.call(self, args[1..-1])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
$console_parser = Console_Parser.new
|
67
|
+
$console_parser.add_command("huhu", proc do |parser, params| puts "jojo huhu hehe" end, 0, "Some help on this")
|
68
|
+
$console_parser.add_command("bla", proc do |parser, params| puts "jojo huhu hehe" end, 0, "Some help on this")
|
69
|
+
while ((str = gets.chop).downcase != "quit")
|
70
|
+
$console_parser.call_command(str)
|
71
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class XDCC_Pack_Match_Template
|
2
|
+
attr_accessor :minsize, :maxsize, :minsize_unit, :maxsize_unit
|
3
|
+
attr_accessor :botname
|
4
|
+
attr_accessor :packname
|
5
|
+
|
6
|
+
# Initialize to default values
|
7
|
+
def initialize
|
8
|
+
@minsize = nil; @maxsize = nil; @minsize_unit = "M"; @maxsize_unit = "M"
|
9
|
+
@botname = Regexp.new("^.*$", Regexp::IGNORECASE);
|
10
|
+
@packname = Regexp.new("^.*$", Regexp::IGNORECASE);
|
11
|
+
end
|
12
|
+
|
13
|
+
def match(pack)
|
14
|
+
self.match_size(pack) && self.match_botname(pack) && self.match_packname(pack)
|
15
|
+
end
|
16
|
+
|
17
|
+
def match_size(pack)
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def match_botname(pack)
|
22
|
+
pack.irc_user_bot.name =~ @botname
|
23
|
+
end
|
24
|
+
|
25
|
+
def match_packname(pack)
|
26
|
+
pack.name =~ @packname
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'src/Network/IRC_Server'
|
3
|
+
require 'src/Network/XDCC_Announcement_Factory'
|
4
|
+
require 'src/Network/XDCC_Announcement_Storage'
|
5
|
+
require 'src/Network/XDCC_Download_Handler'
|
6
|
+
require 'src/Console/XDCC_Pack_Match_Template'
|
7
|
+
|
8
|
+
# demo
|
9
|
+
class SomeListener
|
10
|
+
def initialize
|
11
|
+
@downloads = Hash.new
|
12
|
+
@handlers = Hash.new
|
13
|
+
@path = "/home/grip/dl/irc"
|
14
|
+
@anns = Array.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_event(caller, eventtype, eventargs)
|
18
|
+
case eventtype
|
19
|
+
when XDCC_Announcement_Storage::ON_ANNOUNCEMENT_NEW then begin
|
20
|
+
puts ""
|
21
|
+
puts eventargs[0].to_s
|
22
|
+
@anns.push(eventargs[0])
|
23
|
+
end
|
24
|
+
|
25
|
+
when XDCC_Download_Handler::ON_SHUTDOWN then begin
|
26
|
+
@handlers[caller].puts("Handler is shutting down")
|
27
|
+
@handlers[caller].close
|
28
|
+
end
|
29
|
+
|
30
|
+
when XDCC_Download_Handler::ON_PACK_REQUESTED then begin
|
31
|
+
@handlers[caller].puts("Requesting pack #{eventargs[0].name}")
|
32
|
+
end
|
33
|
+
|
34
|
+
when XDCC_Download_Handler::ON_QUEUED_LOCALLY then begin
|
35
|
+
@handlers[caller].puts("Pack #{eventargs[0].name} has been locally queued in position #{eventargs[1]} of #{eventargs[2]}")
|
36
|
+
end
|
37
|
+
|
38
|
+
when XDCC_Download_Handler::ON_QUEUED_REMOTELY then begin
|
39
|
+
@handlers[caller].puts("Pack #{eventargs[0].name} has been remotely queued in position #{eventargs[1]} of #{!eventargs[2] ? "??" : eventargs[2]}")
|
40
|
+
end
|
41
|
+
|
42
|
+
when XDCC_Download_Handler::ON_DOWNLOAD_STARTED then begin
|
43
|
+
@handlers[caller].puts("Downloading pack #{eventargs[0].name}")
|
44
|
+
end
|
45
|
+
|
46
|
+
when XDCC_Download_Handler::ON_DOWNLOAD_FINISHED then begin
|
47
|
+
@handlers[caller].puts("Finished downloading pack #{eventargs[0].name}")
|
48
|
+
end
|
49
|
+
|
50
|
+
when XDCC_Download_Handler::ON_DOWNLOAD_FAILED then begin
|
51
|
+
@handlers[caller].puts("Failed to downloading pack #{eventargs[0].name} because of #{eventargs[1]}")
|
52
|
+
end
|
53
|
+
|
54
|
+
when XDCC_Download_Handler::ON_DOWNLOAD_PROGRESS then begin
|
55
|
+
@handlers[caller].puts("Pack #{eventargs[0].name} #{eventargs[1]}% #{eventargs[2]}bytes #{eventargs[3]}kb")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def match_template(template)
|
61
|
+
handler = nil
|
62
|
+
logfilename = ""
|
63
|
+
@anns.each do |ann|
|
64
|
+
ann.packs.each do |pack|
|
65
|
+
if (template.match(pack))
|
66
|
+
puts "New download spotted: #{pack.name}"
|
67
|
+
logfilename = "#{@path}/#{pack.irc_user_bot.name}.log"
|
68
|
+
# Check if there is already a downloader for the bot
|
69
|
+
if !@downloads.key?(pack.irc_user_bot)
|
70
|
+
handler = XDCC_Download_Handler.new(pack.irc_user_bot)
|
71
|
+
@downloads[pack.irc_user_bot] = handler
|
72
|
+
@handlers[handler] = File.new(logfilename, File::CREAT | File::APPEND | File::WRONLY)
|
73
|
+
@handlers[handler].sync = true
|
74
|
+
puts "Writing log to #{logfilename}"
|
75
|
+
handler.connect_to_events(XDCC_Download_Handler::ON_ALL_EVENTS, self)
|
76
|
+
else
|
77
|
+
handler = @downloads[pack.irc_user_bot]
|
78
|
+
puts "Appending log to #{logfilename}"
|
79
|
+
end
|
80
|
+
# Add pack to handler
|
81
|
+
handler.add_pack(pack, @path)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Main ###############################################
|
89
|
+
Thread.abort_on_exception = true
|
90
|
+
|
91
|
+
#s = IRC_Server.new
|
92
|
+
#s.connect("irc.freshirc.net", 6667, "dataxb", "wuff")
|
93
|
+
#s.join("#ocs")
|
94
|
+
|
95
|
+
s = IRC_Server.new
|
96
|
+
s.connect("192.168.0.7", 6667, "wuff", "data")
|
97
|
+
s.join("#xdcc-test")
|
98
|
+
|
99
|
+
ann_fact = XDCC_Announcement_Factory.new
|
100
|
+
ann_fact.add_irc_server(s)
|
101
|
+
|
102
|
+
l = SomeListener.new
|
103
|
+
|
104
|
+
storage = XDCC_Announcement_Storage.new(ann_fact)
|
105
|
+
storage.connect_to_events(XDCC_Announcement_Storage::ON_ANNOUNCEMENT_NEW, l)
|
106
|
+
|
107
|
+
|
108
|
+
while ((str = gets.chop) != "quit")
|
109
|
+
if str == "list"
|
110
|
+
p s.user_list
|
111
|
+
elsif str == "template"
|
112
|
+
puts "botreg:"; botreg = gets.chop
|
113
|
+
puts "packreg:"; packreg = gets.chop
|
114
|
+
|
115
|
+
t = XDCC_Pack_Match_Template.new
|
116
|
+
t.botname = Regexp.new(botreg, Regexp::IGNORECASE)
|
117
|
+
t.packname = Regexp.new(packreg, Regexp::IGNORECASE)
|
118
|
+
|
119
|
+
l.match_template(t)
|
120
|
+
else
|
121
|
+
s.send(IRC_Message.parse(str.gsub(/\\001/, "\001") +"\r\n"))
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (c) 2004, Christoph Heindl and Martin Ankerl
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
#
|
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
|
+
#
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
17
|
+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
18
|
+
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
19
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
21
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
22
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
23
|
+
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
24
|
+
|
25
|
+
# Shows a nifty �ber-cool about dialog.
|
26
|
+
class About_Dialog < FXMessageBox
|
27
|
+
# Set parent
|
28
|
+
def initialize(parent)
|
29
|
+
@sep = "\n * "
|
30
|
+
text = create_text
|
31
|
+
super(parent, $cfg.app.name, text, $cfg.icons.app_mega, MBOX_OK|DECOR_TITLE|DECOR_BORDER)
|
32
|
+
end
|
33
|
+
|
34
|
+
# create the dialog boxes text
|
35
|
+
def create_text
|
36
|
+
text = $cfg.app.name + "\n"
|
37
|
+
text << "#{$cfg.text.version} #{$cfg.app.version}, #{$cfg.text.revision} #{$cfg.app.revision}\n"
|
38
|
+
text << $cfg.app.copyright + "\n\n"
|
39
|
+
text << $cfg.app.url
|
40
|
+
# credits
|
41
|
+
text << "\n\n#{$cfg.text.credits}"
|
42
|
+
text << @sep + $cfg.app.developers.sort_by { rand }.join(@sep)
|
43
|
+
# thanks
|
44
|
+
text << "\n\n#{$cfg.text.thanks}"
|
45
|
+
text << @sep + $cfg.app.thanks.sort_by { rand }.join(@sep)
|
46
|
+
text << "\n\nRuby #{RUBY_VERSION}, "
|
47
|
+
text << "FXRuby #{Fox::fxrubyversion}"
|
48
|
+
text
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
# Copyright (c) 2004, Christoph Heindl and Martin Ankerl
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
# are permitted provided that the following conditions are met:
|
6
|
+
#
|
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
|
+
#
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
17
|
+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
18
|
+
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
19
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
21
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
22
|
+
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
23
|
+
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
24
|
+
|
25
|
+
class Application_Builder
|
26
|
+
def initialize(parent, gui, data, logic)
|
27
|
+
@gui = gui
|
28
|
+
@data = data
|
29
|
+
@parent = parent
|
30
|
+
@logic = logic
|
31
|
+
build_menu(parent)
|
32
|
+
FXVerticalFrame.new(parent , LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0,0,0) do |base|
|
33
|
+
build_main_frame(base) do |left_frame, right_frame, bottom_frame|
|
34
|
+
build_connections(left_frame)
|
35
|
+
build_search(right_frame)
|
36
|
+
build_status(bottom_frame)
|
37
|
+
end
|
38
|
+
build_status_bar(base)
|
39
|
+
end
|
40
|
+
build_dialog_boxes(parent)
|
41
|
+
# return created stuff
|
42
|
+
@gui.close
|
43
|
+
end
|
44
|
+
|
45
|
+
# Build menu controls.
|
46
|
+
def build_menu(parent)
|
47
|
+
FXMenuBar.new(parent , LAYOUT_SIDE_TOP|LAYOUT_FILL_X) do |menu_bar|
|
48
|
+
file = Context_Menu.new(menu_bar, $cfg.text.file)
|
49
|
+
file.add($cfg.text.add_server, $cfg.icons.add) { |*args| @logic.on_add_server_click(*args) }
|
50
|
+
file.add_separator
|
51
|
+
file.add($cfg.text.quit, $cfg.icons.quit) { FXApp::instance.exit }
|
52
|
+
|
53
|
+
help = Context_Menu.new(menu_bar, $cfg.text.help)
|
54
|
+
help.add($cfg.text.about, $cfg.icons.about) { @logic.on_about_click }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Build all dialog boxes.
|
59
|
+
def build_dialog_boxes(parent)
|
60
|
+
@gui.add_server_box = Dialog_Box.new(parent , $cfg.text.specify_server)
|
61
|
+
|
62
|
+
@gui.add_server_box.add($cfg.text.server, FRAME_SUNKEN, nil, true, $cfg.text.enter_ip_or_domain)
|
63
|
+
@gui.add_server_box.add($cfg.text.port, FRAME_SUNKEN|TEXTFIELD_INTEGER, $cfg.network.irc.default_port , true, $cfg.text.the_servers_port)
|
64
|
+
@gui.add_server_box.add($cfg.text.nickname, FRAME_SUNKEN)
|
65
|
+
@gui.add_server_box.add($cfg.text.password, TEXTFIELD_PASSWD|FRAME_SUNKEN, nil, false, nil)
|
66
|
+
|
67
|
+
@gui.join_channel_box = Dialog_Box.new(parent, $cfg.text.add_channel_dialog)
|
68
|
+
@gui.join_channel_box.add($cfg.text.channel, FRAME_SUNKEN, nil, true, $cfg.text.channel_name)
|
69
|
+
@gui.join_channel_box.add($cfg.text.password, TEXTFIELD_PASSWD|FRAME_SUNKEN, nil, false, nil)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Build overall frame layout.
|
73
|
+
def build_main_frame(parent) # :yields: left_frame, right_frame, bottom_frame
|
74
|
+
left = right = bottom = nil
|
75
|
+
# [---]
|
76
|
+
FXSplitter.new(parent, SPLITTER_TRACKING|SPLITTER_VERTICAL|SPLITTER_REVERSED|LAYOUT_FILL_X|LAYOUT_FILL_Y) do |root_splitter|
|
77
|
+
# [ | ]
|
78
|
+
FXSplitter.new(root_splitter, SPLITTER_TRACKING|SPLITTER_HORIZONTAL|LAYOUT_FILL_X|LAYOUT_FILL_Y) do |splitter|
|
79
|
+
left = FXVerticalFrame.new(splitter,
|
80
|
+
FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,$cfg.left.width,0, 0,0,0,0,0,0)
|
81
|
+
right = FXVerticalFrame.new(splitter,
|
82
|
+
FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0,0,0)
|
83
|
+
end
|
84
|
+
bottom = FXVerticalFrame.new(root_splitter,
|
85
|
+
LAYOUT_FILL_X, 0,0,0,$cfg.bottom.height, 0,0,0,0,0,0)
|
86
|
+
end
|
87
|
+
yield(left, right, bottom)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Build the connections frame (on the left side).
|
91
|
+
def build_connections(parent)
|
92
|
+
FXLabel.new(parent, $cfg.text.connections, nil, JUSTIFY_CENTER_X|LAYOUT_FILL_X|FRAME_RAISED)
|
93
|
+
if FOXVERSION=="1.0"
|
94
|
+
@gui.connections = FXTreeList.new(parent, 20, nil, 0,
|
95
|
+
(FRAME_SUNKEN|
|
96
|
+
TREELIST_SINGLESELECT|
|
97
|
+
TREELIST_SHOWS_LINES|
|
98
|
+
TREELIST_SHOWS_BOXES|
|
99
|
+
TREELIST_ROOT_BOXES|
|
100
|
+
LAYOUT_FILL_X|
|
101
|
+
LAYOUT_FILL_Y))
|
102
|
+
else
|
103
|
+
@gui.connections = FXTreeList.new(parent, nil, 0,
|
104
|
+
(FRAME_SUNKEN|
|
105
|
+
TREELIST_SINGLESELECT|
|
106
|
+
TREELIST_SHOWS_LINES|
|
107
|
+
TREELIST_SHOWS_BOXES|
|
108
|
+
TREELIST_ROOT_BOXES|
|
109
|
+
LAYOUT_FILL_X|
|
110
|
+
LAYOUT_FILL_Y))
|
111
|
+
end
|
112
|
+
|
113
|
+
# empty area menu
|
114
|
+
menu_empty_area = Context_Menu.new(@gui.connections)
|
115
|
+
menu_empty_area.add($cfg.text.add_server, $cfg.icons.add) { |*args| @logic.on_add_server_click(*args) }
|
116
|
+
|
117
|
+
# server menu
|
118
|
+
menu_server = Context_Menu.new(@gui.connections) do |menu, sender, sel, data|
|
119
|
+
# menu.data contains the server item
|
120
|
+
# item's data is either CONNECTED, DISCONNECTED, CONNECTING
|
121
|
+
menu.load_state(@data.server_item_to_status[menu.data])
|
122
|
+
end
|
123
|
+
menu_server.add($cfg.text.add_channel, $cfg.icons.add) { |*args| @logic.on_add_channel_click(*args) }
|
124
|
+
menu_server.add_separator
|
125
|
+
menu_server.add($cfg.text.connect, $cfg.icons.connected) { |*args| @logic.on_server_connect_click(*args) }
|
126
|
+
menu_server.add($cfg.text.disconnect, $cfg.icons.disconnected) { |*args| @logic.on_server_disconnect_click(*args) }
|
127
|
+
menu_server.add($cfg.text.remove_server, $cfg.icons.remove) { |*args| @logic.on_remove_server_click(*args) }
|
128
|
+
menu_server.add_separator
|
129
|
+
menu_server.add($cfg.text.show_warning, $cfg.icons.warning) { |*args| @logic.on_show_warning(*args) }
|
130
|
+
menu_server.new_state(Gui_Logic::CONNECTED, true, false, true, true, false)
|
131
|
+
menu_server.new_state(Gui_Logic::CONNECTING, true, false, false, true, false)
|
132
|
+
menu_server.new_state(Gui_Logic::DISCONNECTED, true, true, false, true, false)
|
133
|
+
menu_server.new_state(Gui_Logic::CONNECTION_FAILED, true, true, false, true, true)
|
134
|
+
|
135
|
+
# channel menu
|
136
|
+
menu_channel = Context_Menu.new(@gui.connections)
|
137
|
+
menu_channel.add($cfg.text.remove_channel, $cfg.icons.remove) { |*args| @logic.on_remove_channel_click(*args) }
|
138
|
+
|
139
|
+
@gui.connections.init_clickedItem
|
140
|
+
# which menu to show?
|
141
|
+
@gui.connections.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, data|
|
142
|
+
#item = current_connections_item
|
143
|
+
item = @gui.connections.clickedItem
|
144
|
+
menu = nil
|
145
|
+
if !item
|
146
|
+
menu = menu_empty_area
|
147
|
+
elsif item.parent
|
148
|
+
menu = menu_channel
|
149
|
+
else
|
150
|
+
menu = menu_server
|
151
|
+
end
|
152
|
+
menu.data = item
|
153
|
+
menu.execute(sender, sel, data)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Build search controls
|
158
|
+
def build_search(parent)
|
159
|
+
FXHorizontalFrame.new(parent, LAYOUT_FILL_X|FRAME_RAISED, 0,0,0,0, 0,0,0,0,0,0) do |search_frame|
|
160
|
+
|
161
|
+
@gui.search_label = FXLabel.new(search_frame, $cfg.text.search, nil, LAYOUT_CENTER_Y)
|
162
|
+
search = FXTextField.new(search_frame, 1, nil, 0, LAYOUT_FILL_Y|FRAME_SUNKEN|LAYOUT_FILL_X)
|
163
|
+
search.connect(SEL_CHANGED) { @logic.on_search }
|
164
|
+
@gui.search_field = Empty_Text_Field_Handler.new(search, $cfg.text.what_do_you_want_to_fetch_today)
|
165
|
+
|
166
|
+
# create toggle buttons
|
167
|
+
@gui.search_btn_free_slots = Toggle_Button.new(search_frame, $cfg.icons.free_slots , $cfg.text.free_slots, true) { @logic.on_search }
|
168
|
+
@gui.search_btn_slots_unknown = Toggle_Button.new(search_frame, $cfg.icons.slots_unknown, $cfg.text.slots_unknown, true) { @logic.on_search }
|
169
|
+
@gui.search_btn_packet = Toggle_Button.new(search_frame, $cfg.icons.packet, $cfg.text.no_free_slots, true) { @logic.on_search }
|
170
|
+
|
171
|
+
# icon -> button, required in match?()
|
172
|
+
@data.packet_icon_to_toggle_btn[$cfg.icons.free_slots] = @gui.search_btn_free_slots
|
173
|
+
@data.packet_icon_to_toggle_btn[$cfg.icons.slots_unknown] = @gui.search_btn_slots_unknown
|
174
|
+
@data.packet_icon_to_toggle_btn[$cfg.icons.packet] = @gui.search_btn_packet
|
175
|
+
|
176
|
+
@gui.search_status_label = FXLabel.new(search_frame, $cfg.text.status_label_tooltip, nil, LAYOUT_CENTER_Y)
|
177
|
+
end
|
178
|
+
@gui.packet_list = Packet_List.new(@data, parent, nil, 0, $cfg.list.opts) do |packet_list|
|
179
|
+
packet_list.add_header($cfg.text.bot, 70) { |x| x.downcase }
|
180
|
+
packet_list.add_header($cfg.text.name, 250) { |x| x.downcase }
|
181
|
+
packet_list.add_header($cfg.text.size, 70) { |x| -@logic.size_to_nr(x) }
|
182
|
+
end
|
183
|
+
@gui.packet_list.on_cmd_header(1)
|
184
|
+
|
185
|
+
menu_packet_list = Context_Menu.new(@gui.packet_list) do |menu, sender, sel, data|
|
186
|
+
menu.load_state(menu.data != nil)
|
187
|
+
end
|
188
|
+
|
189
|
+
menu_packet_list.add($cfg.text.download, $cfg.icons.add) { |*args| @logic.on_download_click(*args) }
|
190
|
+
menu_packet_list.new_state(true, true)
|
191
|
+
menu_packet_list.new_state(false, false)
|
192
|
+
@gui.packet_list.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, data|
|
193
|
+
menu_packet_list.data = @logic.current_item(@gui.packet_list)
|
194
|
+
menu_packet_list.execute(sender, sel, data)
|
195
|
+
end
|
196
|
+
@gui.packet_list.connect(SEL_DOUBLECLICKED) do |sender, sel, data|
|
197
|
+
menu_packet_list.data = @logic.current_item(@gui.packet_list)
|
198
|
+
@logic.on_download_click(menu_packet_list, sender, sel, data)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Build status controls (bottom frame).
|
203
|
+
def build_status(parent)
|
204
|
+
# active list
|
205
|
+
active_btn = completed_btn = error_btn = nil
|
206
|
+
FXHorizontalFrame.new(parent, LAYOUT_FILL_X, 0,0,0,0, 0,0,0,0,0,0) do |selection_frame|
|
207
|
+
active_btn = FXButton.new(selection_frame, $cfg.text.active, $cfg.icons.active, nil, 0, ICON_BEFORE_TEXT|FRAME_RAISED|LAYOUT_FILL_X)
|
208
|
+
completed_btn = FXButton.new(selection_frame, $cfg.text.completed, $cfg.icons.completed, nil, 0, ICON_BEFORE_TEXT|FRAME_RAISED|LAYOUT_FILL_X)
|
209
|
+
error_btn = FXButton.new(selection_frame, $cfg.text.error, $cfg.icons.error, nil, 0, ICON_BEFORE_TEXT|FRAME_RAISED|LAYOUT_FILL_X)
|
210
|
+
end
|
211
|
+
@gui.active_list = Packet_List.new(@data, parent, nil, 0, $cfg.list.opts) do |active_list|
|
212
|
+
active_list.add_header($cfg.text.bot, 70) { |x| x.downcase }
|
213
|
+
active_list.add_header($cfg.text.name, 250) { |x| x.downcase }
|
214
|
+
active_list.add_header($cfg.text.size, 70) { |x| -@logic.size_to_nr(x) }
|
215
|
+
active_list.add_header($cfg.text.status, 130) { |x| -@logic.sortable_status(x) }
|
216
|
+
active_list.add_header($cfg.text.speed, 60) { |x| x ? -x.to_f : 0.0 }
|
217
|
+
end
|
218
|
+
@gui.active_list.on_cmd_header(3)
|
219
|
+
menu_active_list = Context_Menu.new(@gui.active_list) do |menu, sender, sel, data|
|
220
|
+
menu.load_state(menu.data != nil)
|
221
|
+
end
|
222
|
+
menu_active_list.add($cfg.text.cancel, $cfg.icons.cancel) { |*args| @logic.on_cancel_download_click(*args) }
|
223
|
+
menu_active_list.new_state(true, true)
|
224
|
+
menu_active_list.new_state(false, false)
|
225
|
+
@gui.active_list.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, data|
|
226
|
+
menu_active_list.data = @logic.current_item(@gui.active_list)
|
227
|
+
menu_active_list.execute(sender, sel, data)
|
228
|
+
end
|
229
|
+
|
230
|
+
# completed list
|
231
|
+
@gui.completed_list = Packet_List.new(@data, parent, nil, 0, $cfg.list.opts) do |completed_list|
|
232
|
+
completed_list.add_header($cfg.text.bot, 70) { |x| x.downcase }
|
233
|
+
completed_list.add_header($cfg.text.name, 250) { |x| x.downcase }
|
234
|
+
completed_list.add_header($cfg.text.size, 70) { |x| -@logic.size_to_nr(x) }
|
235
|
+
completed_list.add_header($cfg.text.checksum, 100) { |x| @logic.sortable_md5_status(x) }
|
236
|
+
end
|
237
|
+
@gui.completed_list.on_cmd_header(1)
|
238
|
+
|
239
|
+
menu_completed_list = Context_Menu.new(@gui.completed_list)
|
240
|
+
menu_completed_list.add($cfg.text.clear_list, $cfg.icons.clear) { @logic.on_clear_completed_list }
|
241
|
+
@gui.completed_list.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, data|
|
242
|
+
menu_completed_list.data = @logic.current_item(@gui.completed_list)
|
243
|
+
menu_completed_list.execute(sender, sel, data)
|
244
|
+
end
|
245
|
+
|
246
|
+
# error list
|
247
|
+
@gui.error_list = Packet_List.new(@data, parent, nil, 0, $cfg.list.opts) do |error_list|
|
248
|
+
error_list.add_header($cfg.text.bot, 70) { |x| x.downcase }
|
249
|
+
error_list.add_header($cfg.text.name, 250) { |x| x.downcase }
|
250
|
+
error_list.add_header($cfg.text.size, 70) { |x| -@logic.size_to_nr(x) }
|
251
|
+
error_list.add_header($cfg.text.status, 100) { |x| x }
|
252
|
+
end
|
253
|
+
@gui.error_list.on_cmd_header(1)
|
254
|
+
|
255
|
+
menu_error_list = Context_Menu.new(@gui.error_list)
|
256
|
+
menu_error_list.add($cfg.text.clear_list, $cfg.icons.clear) { @logic.on_clear_error_list }
|
257
|
+
@gui.error_list.connect(SEL_RIGHTBUTTONRELEASE) do |sender, sel, data|
|
258
|
+
menu_error_list.data = @logic.current_item(@gui.error_list)
|
259
|
+
menu_error_list.execute(sender, sel, data)
|
260
|
+
end
|
261
|
+
|
262
|
+
# create beautiful "tabs"
|
263
|
+
tab_data = {
|
264
|
+
active_btn => @gui.active_list,
|
265
|
+
completed_btn => @gui.completed_list,
|
266
|
+
error_btn => @gui.error_list
|
267
|
+
}
|
268
|
+
tabs = Custom_Tabs.new(tab_data)
|
269
|
+
tabs.show(active_btn)
|
270
|
+
end
|
271
|
+
|
272
|
+
# Build the bottom status bar
|
273
|
+
def build_status_bar(parent)
|
274
|
+
@gui.status_bar = FXStatusBar.new(parent, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER)
|
275
|
+
@gui.speed_widget = Speed_Widget.new(@gui.status_bar, 200, $cfg.text.speed_widget_init) do |val|
|
276
|
+
sprintf("%.1fkb", val)
|
277
|
+
end
|
278
|
+
@gui.speed_widget.slowness = 0.8
|
279
|
+
end
|
280
|
+
end
|