Permalink
Browse files

multiterm: Several fixes and improvements

* Support external terminals
* Support moving plugin between sidebar and msgwin notebooks
* Support showing and hiding tabs
* Remove add tab button for now until it has a menu on it
* Remove use of deprecated VTE function fork_command
* Various other minor changes
  • Loading branch information...
1 parent 3b2af33 commit 9e40f167e28d8e51f2d29e1f9f79775db8f2c1fa @codebrainz codebrainz committed Dec 19, 2011
View
@@ -1,16 +1,10 @@
TODO:
-----
- - Add right-click menu to VTE
+ - Finish right-click menu to VTE
- Add GUI for preferences
- - Make tabs not fill entire space available
- Add a terminal-specific right-click menu to each tab
- Support sending editor selection to active (or specific) terminal
- Get plugin building with Waf build system
- - When no user config file is present copy
- `DATADIR/geany-plugins/multiterm/multiterm.conf` to the user's
- config dir to make a default config file. Currently the default
- config is hardcoded.
- - Support having the main tab be in the sidebar as well as the
- message window.
+ - Fix next/previous tab menu items to work correctly
- Lots of other stuff
View
@@ -71,6 +71,48 @@ namespace MultiTerm
public string filename { get { return _filename; } }
+ public bool show_tabs
+ {
+ get
+ {
+ try { return kf.get_boolean("general", "show_tabs"); }
+ catch (KeyFileError err) { return true; }
+ }
+ set
+ {
+ kf.set_boolean("general", "show_tabs", value);
+ store_eventually();
+ }
+ }
+
+ public string external_terminal
+ {
+ owned get
+ {
+ try { return kf.get_string("general", "external_terminal"); }
+ catch (KeyFileError err) { return "xterm"; }
+ }
+ set
+ {
+ kf.set_string("general", "external_terminal", value);
+ store_eventually();
+ }
+ }
+
+ public string location
+ {
+ owned get
+ {
+ try { return kf.get_string("general", "location"); }
+ catch (KeyFileError err) { return "msgwin"; }
+ }
+ set
+ {
+ kf.set_string("general", "location", value);
+ store_eventually();
+ }
+ }
+
public List<ShellConfig> shell_configs { get { return _shell_configs; } }
}
}
@@ -8,10 +8,39 @@ namespace MultiTerm
public signal void new_window_activate();
public signal void copy_activate();
public signal void paste_activate();
- public signal void show_tabs_activate();
+ public signal void show_tabs_activate(bool show_tabs);
public signal void preferences_activate();
+ public signal bool next_tab_activate();
+ public signal bool previous_tab_activate();
+ public signal void move_to_location_activate(string location);
- public void add_separator()
+ private void on_show_tabs_activate(CheckMenuItem item)
+ {
+ show_tabs_activate(item.active);
+ }
+
+ private void on_next_previous_tab_activate(MenuItem item, bool next)
+ {
+ item.sensitive = next ? next_tab_activate() : previous_tab_activate();
+ }
+
+ private void on_move_to_location(MenuItem item)
+ {
+ if (item.get_data<bool>("location_is_msgwin"))
+ {
+ item.set_label("Move to message window");
+ item.set_data<bool>("location_is_msgwin", false);
+ move_to_location_activate("sidebar");
+ }
+ else
+ {
+ item.set_label("Move to sidebar");
+ item.set_data<bool>("location_is_msgwin", true);
+ move_to_location_activate("msgwin");
+ }
+ }
+
+ private void add_separator()
{
SeparatorMenuItem item = new SeparatorMenuItem();
this.append(item);
@@ -29,15 +58,16 @@ namespace MultiTerm
menu.show();
item = new MenuItem.with_label("Open Tab");
-
item.set_submenu(menu);
item.show();
-
this.append(item);
- foreach (ShellConfig sh in cfg.shell_configs)
+ uint len = cfg.shell_configs.length();
+ for (uint i = 0; i < len; i++)
{
+ ShellConfig sh = cfg.shell_configs.nth_data(i);
item = new MenuItem.with_label(sh.name);
+ item.activate.connect(() => new_shell_activate(sh));
menu.append(item);
item.show();
}
@@ -49,29 +79,56 @@ namespace MultiTerm
add_separator();
+ item = new MenuItem.with_label("Next tab");
+ item.activate.connect(() => on_next_previous_tab_activate(item, true));
+ //this.append(item);
+ //item.show();
+
+ item = new MenuItem.with_label("Previous tab");
+ item.activate.connect(() => on_next_previous_tab_activate(item, false));
+ //this.append(item);
+ //item.show();
+
+ //add_separator();
+
image_item = new ImageMenuItem.from_stock(Gtk.Stock.COPY, null);
image_item.activate.connect(() => copy_activate());
- this.append(image_item);
- image_item.show();
+ //this.append(image_item);
+ //image_item.show();
image_item = new ImageMenuItem.from_stock(Gtk.Stock.PASTE, null);
image_item.activate.connect(() => paste_activate());
- this.append(image_item);
- image_item.show();
+ //this.append(image_item);
+ //image_item.show();
- add_separator();
+ //add_separator();
check_item = new CheckMenuItem.with_label("Show Tabs");
- check_item.activate.connect(() => show_tabs_activate());
+ check_item.active = cfg.show_tabs;
+ check_item.activate.connect(() => on_show_tabs_activate(check_item));
this.append(check_item);
check_item.show();
- add_separator();
+ if (cfg.location == "msgwin")
+ {
+ item = new MenuItem.with_label("Move to sidebar");
+ item.set_data<bool>("location_is_msgwin", true);
+ }
+ else
+ {
+ item = new MenuItem.with_label("Move to message window");
+ item.set_data<bool>("location_is_msgwin", false);
+ }
+ item.activate.connect(() => on_move_to_location(item));
+ this.append(item);
+ item.show();
+
+ //add_separator();
image_item = new ImageMenuItem.from_stock(Gtk.Stock.PREFERENCES, null);
image_item.activate.connect(() => preferences_activate());
- this.append(image_item);
- image_item.show();
+ //this.append(image_item);
+ //image_item.show();
}
}
}
@@ -58,6 +58,9 @@ external_terminal=xterm
# tabs when it restarts.
save_tabs=false
+# Whether to show tabs or not
+show_tabs=true
+
bg_color=#ffffff
fg_color=#000000
font=Monospace 9
View
@@ -8,7 +8,7 @@ namespace MultiTerm
public class Notebook : Gtk.Notebook
{
private Button add_button;
- private Config cfg;
+ public Config cfg;
private ContextMenu? context_menu;
private void on_tab_label_close_clicked(int tab_num)
@@ -17,6 +17,83 @@ namespace MultiTerm
this.remove_terminal(tab_num);
}
+ private void on_show_tabs_activate(bool show_tabs)
+ {
+ this.show_tabs = show_tabs;
+ cfg.show_tabs = show_tabs;
+ }
+
+ private bool on_next_tab_activate()
+ {
+ int n_tabs = this.get_n_pages();
+ int current = this.get_current_page();
+
+ if (current < (n_tabs - 1))
+ {
+ current++;
+ this.set_current_page(current);
+ }
+
+ return (current < (n_tabs - 1)) ? true : false;
+ }
+
+ private bool on_previous_tab_activate()
+ {
+ int current = this.get_current_page();
+
+ if (current > 0)
+ {
+ current--;
+ this.set_current_page(current);
+ }
+
+ return (current > 0) ? true : false;
+ }
+
+ private void on_new_shell_activate(ShellConfig cfg)
+ {
+ add_terminal(cfg);
+ }
+
+ private void on_new_window_activate()
+ {
+ Pid pid;
+ string[] args = { cfg.external_terminal, null };
+
+ try
+ {
+ if (Process.spawn_async(null, args, null, SpawnFlags.SEARCH_PATH, null, out pid))
+ debug("Started external terminal '%s' with pid of '%d'", args[0], pid);
+ }
+ catch (SpawnError err)
+ {
+ warning("Unable to launch external terminal: %s".printf(err.message));
+ }
+ }
+
+ private void on_move_to_location(string location)
+ {
+ Container frame = this.get_parent() as Container;
+ Container parent = frame.get_parent() as Container;
+ Gtk.Notebook new_nb;
+
+ parent.remove(frame);
+
+ if (location == "msgwin")
+ {
+ new_nb = this.get_data<Notebook>("msgwin_notebook");
+ new_nb.append_page(frame, this.get_data<Label>("label"));
+ }
+ else
+ {
+ new_nb = this.get_data<Notebook>("sidebar_notebook");
+ new_nb.append_page(frame, this.get_data<Label>("label"));
+ }
+
+ new_nb.set_current_page(new_nb.page_num(frame));
+ cfg.location = location;
+ }
+
private void on_add_button_style_set()
{
int w, h;
@@ -42,23 +119,19 @@ namespace MultiTerm
private bool on_terminal_right_click_event(EventButton event)
{
if (context_menu == null)
+ {
context_menu = new ContextMenu(cfg);
+ context_menu.show_tabs_activate.connect(on_show_tabs_activate);
+ context_menu.next_tab_activate.connect(on_next_tab_activate);
+ context_menu.previous_tab_activate.connect(on_previous_tab_activate);
+ context_menu.new_shell_activate.connect(on_new_shell_activate);
+ context_menu.new_window_activate.connect(on_new_window_activate);
+ context_menu.move_to_location_activate.connect(on_move_to_location);
+ }
context_menu.popup(null, null, null, event.button, event.time);
return true;
}
- private void show_hide_notebook_tabs()
- {
- /* TODO: once the context menu is added, make this
- * optional in the config file. */
- /*
- if (this.get_n_pages() <= 1)
- this.show_tabs = false;
- else
- this.show_tabs = true;
- */
- }
-
public Terminal add_terminal(ShellConfig cfg)
{
TabLabel label = new TabLabel(cfg.name);
@@ -70,32 +143,30 @@ namespace MultiTerm
term.set_data<TabLabel>("label", label);
term.show_all();
+ term.right_click_event.connect(on_terminal_right_click_event);
this.append_page(term, label);
-
this.set_tab_reorderable(term, true);
-
/* TODO: this is deprecated, try and figure out alternative
* from GtkNotebook docs. */
this.set_tab_label_packing(term, true, true, PackType.END);
this.scrollable = true;
- show_hide_notebook_tabs();
-
return term;
}
public void remove_terminal(int tab_num)
{
this.remove_page(tab_num);
- show_hide_notebook_tabs();
}
public class Notebook(string config_filename)
{
Gtk.Image img;
RcStyle style;
+ cfg = new Config(config_filename);
+
style = new RcStyle();
style.xthickness = 0;
style.ythickness = 0;
@@ -113,10 +184,11 @@ namespace MultiTerm
add_button.show_all();
add_button.style_set.connect(on_add_button_style_set);
- this.set_action_widget(add_button, PackType.END);
+ /* TODO: make this button show a list to select which shell
+ * to open */
+ //this.set_action_widget(add_button, PackType.END);
- cfg = new Config(config_filename);
- //context_menu = new ContextMenu(cfg);
+ this.show_tabs = cfg.show_tabs;
foreach (ShellConfig sh in cfg.shell_configs)
{
Oops, something went wrong.

0 comments on commit 9e40f16

Please sign in to comment.