XDCC-Fetch 1.386
Sign up to get free protection for your applications and to get access to all the features.
- 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
|