2
// Copyright (C) 2011 Adrien Plazas
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
// Adrien Plazas <kekun.plazas@laposte.net>
21
// Daniel Foré <daniel@elementaryos.org>
24
/* Use default system font (tag FIXME)
25
* Set preferences via GSettings ?
26
* Do not focus on buttons
27
* Improve window resize (is it useful ?)
28
* Add right click menu with: copy, paste, preferences?, about
29
* Notify with system bubbles if the window is not focused (tag FIXME)
30
* Set Dan correctly as the artist
38
private class PantheonTerminal : Window
45
bool window_focus = false;
47
Notify.Notification notification;
49
private PantheonTerminal()
51
Gtk.Settings.get_default().gtk_application_prefer_dark_theme = true;
52
set_title("Terminal");
55
destroy.connect(close);
57
// Check if the window have the focus
58
focus_in_event.connect(() => { window_focus = true; return false; });
59
focus_out_event.connect(() => { window_focus = false; return false; });
61
notebook = new Notebook();
62
var left_box = new HBox(false, 0);
63
var right_box = new HBox(false, 0);
66
notebook.set_action_widget(left_box, PackType.START);
67
notebook.set_action_widget(right_box, PackType.END);
68
notebook.set_scrollable(true);
71
left_box.set_size_request(10, 0);
73
// Set "New tab" button
74
var add_button = new Button();
75
add_button.set_image(new Image.from_stock(Stock.ADD, IconSize.MENU));
77
add_button.set_relief(ReliefStyle.NONE);
78
add_button.set_tooltip_text("Open a new tab");
79
add_button.clicked.connect(new_tab);
80
right_box.pack_start(add_button, false, false, 0);
82
// Get the system's style
84
font = FontDescription.from_string(system_font());
85
bgcolor = get_style().bg[StateType.NORMAL];
86
fgcolor = get_style().fg[StateType.NORMAL];
88
// Try to set the icon FIXME
89
Gdk.Pixbuf icon = new Gdk.Pixbuf(Gdk.Colorspace.RGB, true, 8, 1, 1);
90
try { IconTheme.get_default().load_icon("terminal", 16, IconLookupFlags.FORCE_SVG); } catch (Error er) {}
91
try { set_icon(icon); } catch(Error er) {}
97
static string system_font()
99
string font_name = null;
100
/* Wait for GNOME 3 FIXME
101
* var settings = new GLib.Settings("org.gnome.desktop.interface");
102
* font_name = settings.get_string("monospace-font-name");
104
font_name = "Droid Sans Mono 10";
108
private void new_tab()
111
var t = new TerminalWithNotification();
112
t.fork_command(null,null,null,null, true, true,true);
114
// Test the "task_over" signal
115
t.task_over.connect(() => {stdout.printf("task_over\n");});
119
// Create a new tab with the terminal
120
var tab = new TabWithCloseButton("Terminal");
121
notebook.insert_page(t, tab, notebook.get_current_page() + 1);
122
notebook.next_page();
123
notebook.set_tab_reorderable(t, true);
126
tab.clicked.connect(() => { notebook.remove(t); });
127
t.window_title_changed.connect(() => { tab.set_text(t.get_window_title()); });
128
notebook.switch_page.connect((page, page_num) => { if (notebook.page_num(t) == (int) page_num) tab.set_notification(false); });
129
focus_in_event.connect(() => { if (notebook.page_num(t) == notebook.get_current_page()) tab.set_notification(false); return false; });
132
t.task_over.connect(() => {
133
if (notebook.page_num(t) != notebook.get_current_page() || !window_focus)
134
tab.set_notification(true);
136
//~ notification = (Notify.Notification)GLib.Object.new (
137
//~ typeof (Notify.Notification),
138
//~ "summary", "sum",
139
//~ "body", "message",
140
//~ "icon-name", "");
142
//~ notification = new Notification("test", "test", "test");
143
//~ try { notification.show(); }
146
stdout.printf("focus\n");
151
t.set_color_background(bgcolor);
152
t.set_color_foreground(fgcolor);
160
private static void main(string[] args)
163
new PantheonTerminal();
168
public class TerminalWithNotification : Terminal
170
public signal void task_over();
172
long last_row_count = 0;
173
long last_column_count = 0;
175
public TerminalWithNotification()
177
set_size_request(320, 200);
178
window_title_changed.connect(check_for_notification);
181
private void check_for_notification()
183
/* Curently I use this trick to know if a task is over, the drawnback is
184
* that when the window is resized and a notification should be received,
185
* the user will not be notified.
187
if (get_row_count() == last_row_count && get_column_count() == last_column_count)
189
last_row_count = get_row_count();
190
last_column_count = get_column_count();
194
public class TabWithCloseButton : HBox
196
public signal void clicked();
198
private Button button;
201
bool notification = false;
203
public TabWithCloseButton(string text)
208
button = new Button();
209
button.set_image(new Image.from_stock(Stock.CLOSE, IconSize.MENU));
211
button.set_relief(ReliefStyle.NONE);
212
button.clicked.connect(() => { clicked(); });
215
label = new Label(text);
219
pack_start(button, false, true, 0);
220
pack_end(label, true, true, 0);
224
public void set_notification(bool notification)
226
this.notification = notification;
228
{ label.set_markup("<span color=\"#18a0c0\">"+text+"</span>"); }
230
{ label.set_markup(text); }
233
public void set_text(string text)
236
set_notification(notification);