-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathopen.vala
154 lines (143 loc) · 4.22 KB
/
open.vala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* Create an open new session dialog
*/
[GtkTemplate (ui = "/name/masella/tabbedmux/open.ui")]
public class TabbedMux.OpenDialog : Gtk.Dialog {
public bool success = false;
[GtkChild]
private unowned Gtk.RadioButton remote_connection;
[GtkChild]
private unowned Gtk.Entry user;
[GtkChild]
private unowned Gtk.Entry host;
[GtkChild]
private unowned Gtk.Entry port;
[GtkChild]
private unowned Gtk.Entry session;
[GtkChild]
private unowned Gtk.Entry binary;
[GtkChild]
private unowned Gtk.CheckButton save;
internal OpenDialog (Window parent) {
Object (application: parent.application, transient_for: parent);
}
[GtkCallback]
private void on_cancel () {
destroy ();
}
/**
* If the user start typing in an SSH-only box, flip the connection type.
*/
[GtkCallback]
private void on_ssh_changed () {
if (!remote_connection.active) {
remote_connection.active = true;
}
}
/**
* Validate the user input, try to create a session (blocking) and then register it with the application.
*/
[GtkCallback]
private void on_connect () {
try {
/* Validate fields common to SSH and local. */
var session_name = strip (session.text);
if (":" in session_name) {
show_error (this, "Session names may not contain colons.");
return;
}
if (session_name.length == 0) {
session_name = "0";
}
var tmux_binary = strip (binary.text);
if (tmux_binary.length == 0) {
tmux_binary = "tmux";
}
if (remote_connection.active) {
/* SSH. Validate all the fields. */
var hostname = strip (host.text);
if (hostname.length == 0) {
show_error (this, "Host is missing.");
return;
}
uint64 port_number = 22;
var port_text = strip (port.text);
if (port_text.length != 0) {
if (!uint64.try_parse (strip (port.text), out port_number)) {
show_error (this, "Port is not a number.");
return;
}
if (port_number > ushort.MAX) {
show_error (this, "Port is too large.");
return;
}
}
var username = strip (user.text);
if (username.length == 0) {
username = Environment.get_user_name ();
}
/* Create a handler for the password/prompts. */
var busy_dialog = new BusyDialog (this);
var keybd_dialog = new KeyboardInteractiveDialog (busy_dialog, host.text);
busy_dialog.show ();
TMuxSshStream.open.begin (session_name, host.text, (uint16) port_number, username, tmux_binary, keybd_dialog.respond, busy_dialog, (sender, result) => {
try {
var stream = TMuxSshStream.open.end (result);
/* Save if desired */
if (stream != null && save.active && application is Application) {
((Application) application).saved_sessions.append_ssh (session_name, host.text, (uint16) port_number, username, tmux_binary);
}
deal_with_stream (stream);
} catch (IOError.CANCELLED e) {
} catch (Error e) {
show_error (this, e.message);
}
keybd_dialog.destroy ();
busy_dialog.destroy ();
});
} else {
/* Local. Don't validate SSH fields. */
var stream = TMuxLocalStream.open (session_name, tmux_binary);
/* Save if desired */
if (stream != null && save.active && application is Application) {
((Application) application).saved_sessions.append_local (session_name, tmux_binary);
}
deal_with_stream (stream);
}
} catch (IOError.CANCELLED e) {
} catch (Error e) {
show_error (this, e.message);
}
}
/* Deal with the connection attempt. */
void deal_with_stream (TMuxStream? stream) {
if (stream == null) {
show_error (this, "Could not connect.");
} else {
((Application) application).add_stream ((!)stream);
success = true;
destroy ();
}
}
}
[GtkTemplate (ui = "/name/masella/tabbedmux/busy.ui")]
public class TabbedMux.BusyDialog : Gtk.Dialog {
[GtkChild]
private unowned Gtk.Label text;
public string message {
set {
text.label = value;
}
}
public Cancellable cancellable {
get; private set;
}
public BusyDialog (Gtk.Window parent) {
Object (application : parent.application, transient_for: parent);
cancellable = new Cancellable ();
}
[GtkCallback]
private void on_cancel () {
cancellable.cancel ();
}
}