├── AUTHORS ├── COPYING ├── INSTALL ├── Makefile ├── README.md ├── altyo_config.vala ├── altyo_hotkey.vala ├── altyo_myoverlaybox.vala ├── altyo_quick_connectios.vala ├── altyo_settings.vala ├── altyo_terminal.vala ├── altyo_window.vala ├── data ├── altyo.desktop ├── altyo.gresource.xml ├── altyo.png ├── altyo.svg ├── altyo_standalone.desktop ├── encodings_list.glade ├── main_window_encodings_combo.glade └── preferences.glade ├── hvbox.vala ├── main.vala ├── po ├── altyo.po └── ru │ └── LC_MESSAGES │ └── altyo.po └── vapi ├── config.vapi ├── vte-2.90.deps ├── vte-2.90.vapi └── xkb.vapi /AUTHORS: -------------------------------------------------------------------------------- 1 | Konstantinov Denis -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Basic Installation 2 | ================== 3 | To compile you need header files for 4 | glib 2.32 or newer 5 | gtk 3.4 or newer (for Xorg server) 6 | libvte 0.30.1 or newer 7 | vala 0.16 or newer 8 | 9 | Type `make' to compile the package. 10 | 11 | Type `make install' to install the programs and any data files and 12 | documentation. When installing into a prefix owned by root, it is 13 | recommended that the package be configured and built as a regular 14 | user, and only the `make install' phase executed with root 15 | privileges. 16 | 17 | By default program will installed into /usr, you can override install 18 | directory by PREFIX variable. 19 | For example: `PREFIX=/usr/local make install' 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PRG_NAME=altyo 2 | 3 | # guess Linux distro 4 | LINUX.DISTRIB.FILE=$(shell ls /etc/lsb-release 2>/dev/null) 5 | ifeq ($(LINUX.DISTRIB.FILE),) 6 | LINUX.DISTRIB.FILE=$(shell ls /etc/debian_version 2>/dev/null) 7 | endif 8 | 9 | ifeq ($(LINUX.DISTRIB.FILE),/etc/lsb-release) 10 | LINUX.DISTRIB.ID=$(shell grep DISTRIB_ID /etc/lsb-release | sed 's/DISTRIB_ID=//') 11 | endif 12 | 13 | ifeq ($(LINUX.DISTRIB.FILE),/etc/debian_version) 14 | LINUX.DISTRIB.ID=debian 15 | endif 16 | 17 | ifeq ($(LINUX.DISTRIB.ID),Ubuntu) 18 | LINUX.DISTRIB.ID=ubuntu 19 | endif 20 | 21 | CHANGELOG_TAG=${shell grep -m 1 "^altyo" ./debian/changelog | sed 's/.*(//' | sed 's/).*$$//'| sed 's/~/_/' | sed 's/:/%/'} 22 | GIT_HASH=${shell which git >/dev/null && git log -1 --pretty=format:%h} 23 | VALA_FLAGS ?= 24 | INSTALL?=install -v 25 | AWK?=awk 26 | XARGS=xargs 27 | 28 | INSTALLED_FILES:=$(shell $(AWK) '/.* -> .*/{print $$3}' .install_log | $(XARGS)) 29 | 30 | #use tmpfs for ssd hard drive 31 | TMPFS=$(shell ls -d ./tmpfs 2>/dev/null) 32 | ifeq ($(TMPFS),./tmpfs) 33 | $(shell `[ \( -L ./tmpfs \) -a \( -e ./tmpfs \) ] || mkdir -p /run/shm/altyo_build; rm -rf ./tmpfs ; ln -s /run/shm/altyo_build ./tmpfs` ) 34 | VALA_FLAGS += -d ./tmpfs 35 | endif 36 | 37 | VALA_FLAGS += -v 38 | VALA_FLAGS += --disable-warnings 39 | #VALA_FLAGS += -g --save-temps -X -O0 40 | VALA_FLAGS += -X -DGETTEXT_PACKAGE=\"$(PRG_NAME)\" -X -DAY_GIT_HASH=\"$(GIT_HASH)\" -X -DAY_CHANGELOG_TAG=\"$(CHANGELOG_TAG)\" 41 | #\ -I.\ -include\ "./config.h" -v 42 | ifeq ($(LINUX.DISTRIB.ID),ubuntu) 43 | #debian specific possibility 44 | VALA_FLAGS += -D ALTERNATE_SCREEN_SCROLL 45 | endif 46 | 47 | VTE ?= $(shell pkg-config --exists vte-2.91 && echo 2.91) 48 | VTE ?= $(shell pkg-config --exists vte-2.90 && echo 2.90) 49 | 50 | VALA_FLAGS += --vapidir ./vapi --pkg gtk+-3.0 --pkg gdk-x11-3.0 --pkg cairo --pkg posix --pkg gmodule-2.0 51 | 52 | 53 | 54 | ifeq ($(VTE),2.91) 55 | VALA_FLAGS += -D VTE_2_91 56 | VALA_FLAGS += --pkg vte-2.91 57 | else 58 | VALA_FLAGS += --pkg vte-2.90 59 | endif 60 | 61 | #DESTDIR?= 62 | PREFIX?=/usr 63 | 64 | VALA_FILES = vapi/config.vapi \ 65 | vapi/xkb.vapi \ 66 | main.vala \ 67 | hvbox.vala \ 68 | altyo_terminal.vala \ 69 | altyo_window.vala \ 70 | altyo_hotkey.vala \ 71 | altyo_config.vala \ 72 | altyo_settings.vala \ 73 | data/altyo.c 74 | # altyo_myoverlaybox.vala 75 | 76 | #VALA_FLAGS += --pkg gnome-keyring-1 -D HAVE_QLIST 77 | #VALA_FILES += altyo_quick_connectios.vala 78 | 79 | GLADE_FILES = data/preferences.glade data/encodings_list.glade data/main_window_encodings_combo.glade 80 | 81 | 82 | default: data/altyo.c 83 | #test -e ./altyo && rm ./altyo 84 | valac -o $(PRG_NAME) $(VALA_FLAGS) $(VALA_FILES) 85 | 86 | source: data/altyo.c 87 | valac -C -H $(VALA_FLAGS) $(VALA_FILES) 88 | 89 | data/altyo.c: data/altyo.gresource.xml data/altyo.svg $(GLADE_FILES) 90 | glib-compile-resources --sourcedir=./data --generate-source ./data/altyo.gresource.xml 91 | 92 | clean: 93 | rm *.c *.h || true 94 | rm ./altyo || true 95 | rm ./data/*.c *.h || true 96 | 97 | install: gen_mo 98 | test -z "$(DESTDIR)$(PREFIX)/bin" || mkdir -p "$(DESTDIR)$(PREFIX)/bin"; 99 | $(INSTALL) -m 0755 ./$(PRG_NAME) $(DESTDIR)$(PREFIX)/bin >>.install_log 100 | test -z "$(DESTDIR)$(PREFIX)/share/applications" || mkdir -p "$(DESTDIR)$(PREFIX)/share/applications"; 101 | $(INSTALL) -m 0644 ./data/altyo.desktop $(DESTDIR)$(PREFIX)/share/applications >>.install_log 102 | $(INSTALL) -m 0644 ./data/altyo_standalone.desktop $(DESTDIR)$(PREFIX)/share/applications >>.install_log 103 | test -z "$(DESTDIR)$(PREFIX)/share/locale/ru/LC_MESSAGES" || mkdir -p "$(DESTDIR)$(PREFIX)/share/locale/ru/LC_MESSAGES"; 104 | $(INSTALL) -m 0644 ./po/ru/LC_MESSAGES/altyo.mo $(DESTDIR)$(PREFIX)/share/locale/ru/LC_MESSAGES >>.install_log 105 | test -z "$(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps" || mkdir -p "$(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps"; 106 | $(INSTALL) -m 0644 ./data/altyo.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/48x48/apps >>.install_log 107 | test -z "$(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps" || mkdir -p "$(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps"; 108 | $(INSTALL) -m 0644 ./data/altyo.svg $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps >>.install_log 109 | 110 | uninstall: .install_log $(INSTALLED_FILES) 111 | rm -f $? 112 | 113 | gen_po: 114 | xgettext -o ./po/altyo.po --from-code=UTF-8 -language=C --keyword=_ --keyword=N_ $(VALA_FILES) $(GLADE_FILES) 115 | msgmerge -s -U ./po/ru/LC_MESSAGES/$(PRG_NAME).po ./po/$(PRG_NAME).po 116 | 117 | gen_mo: 118 | msgfmt -c -v -o ./po/ru/LC_MESSAGES/$(PRG_NAME).mo ./po/ru/LC_MESSAGES/$(PRG_NAME).po 119 | 120 | source-package: 121 | rm ./altyo || true 122 | rm ./po/ru/LC_MESSAGES/$(PRG_NAME).mo || true 123 | gbp buildpackage --git-upstream-tree=branch --git-upstream-branch=master -rfakeroot -S -sa 124 | sed -i -re '1 s/(altyo \(.*)\) .*\;/\1~trusty\) trusty\;/' ./debian/changelog 125 | dpkg-buildpackage -S -sa 126 | git checkout ./debian/changelog 127 | sed -i -re '1 s/(altyo \(.*)\) .*\;/\1~xenial\) xenial\;/' ./debian/changelog 128 | dpkg-buildpackage -S -sa 129 | git checkout ./debian/changelog 130 | sed -i -re '1 s/(altyo \(.*)\) .*\;/\1~zesty\) zesty\;/' ./debian/changelog 131 | dpkg-buildpackage -S -sa 132 | git checkout ./debian/changelog 133 | sed -i -re '1 s/(altyo \(.*)\) .*\;/\1~artful\) artful\;/' ./debian/changelog 134 | dpkg-buildpackage -S -sa 135 | git checkout ./debian/changelog 136 | 137 | gen_changes: 138 | gbp dch --ignore-branch --debian-branch=master --verbose -a -R 139 | git add . 140 | $(MAKE) gen_changes_stage2 141 | 142 | gen_changes_stage2: 143 | git commit -m "new: debian release $(CHANGELOG_TAG)" 144 | git tag "debian/$(CHANGELOG_TAG)" 145 | git push 146 | git push origin --tags 147 | 148 | #git tag "debian/0.2_121003-linvinus1" ~ -> _ , : -> % 149 | #git-dch --ignore-branch --debian-branch=master --verbose 150 | #git push origin --tags 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AltYo 2 | ===== 3 | 4 | AltYo - drop-down terminal emulator, written in Vala, depends only on libvte and gtk3. 5 | 6 | Main program advantages. 7 | ------------------------ 8 | * The design of altyo allows to open an unlimited tab count, even with long terminal titles. 9 | if tabs do not fit in one row, they will move to a new line. 10 | * Drag and drop tabs. 11 | * Tabs do not stand out from the terminal. (solid view) 12 | * Title of the tabs fully customisable. 13 | Highlight parts of the terminal header by color (for example, highlight username and hostname) 14 | Adjust the header of the terminal, using regular expressions(for example cut unnecessary parts). 15 | * Autostart with desktop session. 16 | * Autostarts programs in new tabs ,for example start mocp and mutt, by default. 17 | * Alert popup shows when you the terminal will be closed with an important program (ssh, wget pattern is customizable), even if executed in the background. 18 | * Delayed "Close tab", 10 seconds before tab will actually be closed. If necessary, `R` can be pressed to restore the closed tab, tabs can also be restored from the terminal popup menu. 19 | * Important tabs can be 'Locked', the program will then ask to confirm tab closing. ("Lock tab" is in from the context menu on tab button) 20 | * All options can be configured via graphical settings dialog. 21 | * The program will warn the user when incorrect values are filled in the configuration, if settings are absent in config file, the program will use the default values. 22 | * Hotkey for ~~the first 20~~ unlimited tabs (double press of `alt+5` will switch to the 15th tab, triple press will switch to the 25th tab and so on) 23 | * You may use css to style the program (thanks to gtk3) 24 | * Multi monitor support. 25 | * The monitor in which altYo is started by default can be configured. 26 | * Individual window size and position for each monitor. 27 | * Program contains "Follow the mouse" mode, after hiding, window will shown on the monitor with mouse pointer. 28 | * Tiling window manager support (usual window). 29 | Use `--standalone` command line option to run in tiling window manager, 30 | For any other window managers, altyo will operate as usual terminal emulator (like xterm). 31 | * Multiple instances. You may run several instances of alto in same time. 32 | In order to do that, an unique id and configuration file for each instance should be setup. 33 | For example: 34 | `altyo --id=org.gtk.altyo_left_monitor -c ~/.config/altyo/config_left_monitor.ini` 35 | `altyo --id=org.gtk.altyo_right_monitor -c ~/.config/altyo/config_right_monitor.ini` 36 | now each instance can be controlled individually 37 | `altyo --id=org.gtk.altyo_left_monitor -e "htop"` 38 | `altyo --id=org.gtk.altyo_right_monitor -e "mc"` 39 | The id can be omitted: `--id=none` may be used, but in that case there will be no possibility to control instances from the command line. 40 | 41 | [![Main window](http://storage6.static.itmages.ru/i/13/0406/s_1365230653_4853839_d41d8cd98f.png)](http://itmages.ru/image/view/971951/d41d8cd9) 42 | [![Preferences Look and feel](http://storage3.static.itmages.ru/i/13/0406/s_1365229810_3352986_d41d8cd98f.png)](http://itmages.ru/image/view/971932/d41d8cd9) 43 | [![Preferences Key bindings](http://storage5.static.itmages.ru/i/13/0406/s_1365229912_4764716_d41d8cd98f.png)](http://itmages.ru/image/view/971933/d41d8cd9) 44 | [![Preferences Advanced](http://storage6.static.itmages.ru/i/13/0406/s_1365229959_4473970_d41d8cd98f.png)](http://itmages.ru/image/view/971934/d41d8cd9) 45 | [![Tiling window manager](http://storage3.static.itmages.ru/i/13/0612/s_1371022015_7777413_5cf29d0faf.png)](http://itmages.ru/image/view/1071250/5cf29d0f) 46 | [![Tiling window manager](http://storage5.static.itmages.ru/i/13/0612/s_1371022059_3043913_a19d77ddef.png)](http://itmages.ru/image/view/1071252/a19d77dd) 47 | [![Normal window](http://storage2.static.itmages.ru/i/13/0612/s_1371037750_9206122_f69d88b067.png)](http://itmages.ru/image/view/1071578/f69d88b0) 48 | 49 | small video presentation of the available features: 50 | * youtube video altyo 0.3 51 | [![youtube altyo 0.3](http://img.youtube.com/vi/IEabsuFresk/0.jpg)](http://youtu.be/IEabsuFresk) 52 | * altyo 0.2 http://youtu.be/9W8m6T7HyVs and http://youtu.be/utxeh-SBTvI 53 | 54 | Installing 55 | ---- 56 | Packages for *Ubuntu and Debian* available there https://launchpad.net/~linvinus/+archive/altyo 57 | Package for *Arch Linux* AUR https://aur.archlinux.org/packages/altyo-git/ (package created by willemw) 58 | Ebuild for *Gentoo/Sabayon* https://drive.google.com/file/d/0B6vs0mKF7AyLQzdYOEdEVzJOZWM/view?usp=sharing (ebuild created by giacomogiorgianni) 59 | 60 | Source code available there https://github.com/linvinus/AltYo 61 | How to install from sources is described in INSTALL file. 62 | 63 | Tips and tricks: 64 | ---- 65 | 1. A new stand-alone terminal may always be opened in current directory by pressing `N` (default key binding). 66 | 2. In search mode (when text entry have a focus), the following hotkeys may be used: 67 | `ctrl+1` - toggle "Wrap search" 68 | `ctrl+2` - toggle "Match case-sensitive" 69 | `ctrl+3` - toggle search mode "terminal text"/"terminals titles" 70 | `ctrl+Up` or `Enter` - find next 71 | `ctrl+Down` - find prev 72 | `Up` - search history 73 | `Down` - search history 74 | `Esc` - close search dialog 75 | (Soddy, but those shortcuts are hardcoded). 76 | 3. Switching tabs by searching in the titles. 77 | In order to switch tabs by searching a search dialog `F` (default key binding) should be opened, 78 | then the search option "terminals titles" has to be activated, by pressing ``. 79 | Type in order to search for part of the tab titles. 80 | The hotkeys : 81 | `ctrl+Up` or `Enter` - find next 82 | `ctrl+Down` - find prev 83 | can be used to cycle through the search results 84 | Also, you may configure special hotkeys to quickly activate the "Search in terminals titles" mode. 85 | 4. Tabs can be sorted by hostname (if tab title contains host name in the following form `@:`) 86 | To do that after pressing right mouse button on tab title, in the context menu, select "Sort by hostname" 87 | Also, you may configure a special hotkey for the "Sort by hostname" action. 88 | 5. Altyo is portable, the executable file can be copied on an USB flash drive. 89 | The only requirement on the target machine is that Gtk 3.4 or newer and libvte 3.0 or newer sould be installed. 90 | Those libraries should be available on fresh distributives. 91 | 6. Double click on an empty space in the tab bar will open a new tab. 92 | 7. Middle mouse button click on a tab button will close the tab. 93 | 8. You may set the default TERM variable at Advanced -> Terminal regexps ->TERM, e.g. `TERM=xterm-256color` 94 | 95 | FAQ: 96 | ---- 97 | * Q) ubuntu "global menu" + alt+grave 98 | "global menu" show application menu, when user press alt+grave, but it should not 99 | * A) disable gtk3 auto mnemonics 100 | ``` 101 | dconf write /org/gnome/desktop/interface/automatic-mnemonics false 102 | ``` 103 | 104 | * Q) when resizing terminal, lines break, if you are running Zsh 105 | * A) bug is described there https://bugzilla.gnome.org/show_bug.cgi?id=708213 and there https://bbs.archlinux.org/viewtopic.php?pid=1246865 106 | ~~you need to apply patch (https://bbs.archlinux.org/viewtopic.php?pid=1246865#p1246865). 107 | to resolve that. 108 | for ubuntu users, patched vte available in this ppa https://launchpad.net/~linvinus/+archive/vte~~ 109 | this bug resolved in vte 0.36 110 | 111 | * Q) Window gravity south, not working under xfwm4 112 | * A) it is xfwm4 bug https://bugzilla.xfce.org/show_bug.cgi?id=3634 113 | 114 | * Q) tabs does not close after entering "exit" command (mc restarting after pressing F10 if it was runned as autorun command) 115 | * A) if you prefer close tabs by "exit" command, you may turn off option "Auto restart shell" 116 | 117 | * Q) "auto run" commands doesn't see environment variables from bashrc file 118 | * A) this happen because they are running as standalone application, 119 | but, for example, you may use following wrap around `bash -c "EDITOR=vim mc"` 120 | in this example mc will runned with special environment variable 121 | 122 | * Q) F11 (maximize) not working in lubuntu (with openbox) 123 | * A) you need to remove following lines in ~/.config/openbox/lubuntu-rc.xml 124 | ` 125 | 126 | ` 127 | 128 | * Q) Missing terminal focus-in (libvte bug) 129 | * A) Bug report is here https://bugzilla.gnome.org/show_bug.cgi?id=677329 130 | https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=699907 131 | resolved in Ubuntu 12.04 updates xserver-xorg-core-lts-trusty >= 2:1.15.1-0ubuntu2~precise2 132 | resolved in Ubuntu 14.04 and newer 133 | Workarounds: 134 | 1) ~~window.unrealize();~~ 135 | 2) ~~export GDK_CORE_DEVICE_EVENTS=1~~ 136 | 3) Set checkbox "Workaround if focus lost" in settings, then restart altyo. 137 | 138 | 139 | Reviews about AltYo 140 | ------------------- 141 | Video Review from Noah and Chris in Linux Action Show The worlds #1 Linux podcast. https://www.youtube.com/watch?v=RJyBoqvQg54#t=665 (http://www.jupiterbroadcasting.com/show/linuxactionshow/) 142 | 143 | zenway.ru (Russian) http://zenway.ru/page/altyo 144 | muhas.ru (Russian) http://muhas.ru/?p=202 145 | -------------------------------------------------------------------------------- /altyo_config.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | using Gtk; 19 | 20 | 21 | #if VALA_0_17 22 | #else 23 | /* VALA_0_16 and older 24 | * quirk for Ubuntu precise (12.04) 25 | * bug 675403. 26 | * https://mail.gnome.org/archives/commits-list/2012-June/msg05401.html 27 | */ 28 | [CCode (cname = "gtk_style_context_lookup_color")] 29 | extern bool vala_016_style_context_lookup_color(Gtk.StyleContext context,string color_name,out Gdk.RGBA color); 30 | #endif 31 | 32 | public enum CFG_CHECK{ 33 | OK, 34 | REPLACE, 35 | USE_DEFAULT 36 | } 37 | 38 | public enum VER{ 39 | major, 40 | minor, 41 | rc 42 | } 43 | 44 | public enum DISTRIB_ID{ 45 | UBUNTU, 46 | OTHER 47 | } 48 | 49 | public delegate CFG_CHECK check_string(ref string s); 50 | public delegate CFG_CHECK check_string_list(ref string[] sl); 51 | public delegate CFG_CHECK check_integer(ref int i); 52 | public delegate CFG_CHECK check_double(ref double d); 53 | public delegate CFG_CHECK check_boolean(ref bool b); 54 | public delegate CFG_CHECK check_integer_list(ref int[] il); 55 | 56 | [SimpleType] 57 | public enum CFG_TYPE{ 58 | TYPE_UNKNOWN, 59 | TYPE_BOOLEAN, 60 | TYPE_DOUBLE, 61 | TYPE_INTEGER, 62 | TYPE_STRING, 63 | TYPE_STRING_LIST, 64 | TYPE_ACCEL_STRING, 65 | TYPE_INTEGER_LIST, 66 | } 67 | 68 | 69 | public class MySettings : Object { 70 | private KeyFile kf; 71 | public string conf_file; 72 | private string profile {get;set;default = "profile0";} 73 | private string accel_section {get;set;default = "KeyBindings";} 74 | private string qconnection_section {get;set;default = "QConnections";} 75 | public bool opened {get;set; default = false;} 76 | private bool changed {get;set; default = false;} 77 | private HashTable typemap; 78 | public bool disable_hotkey = false; 79 | public bool standalone_mode = false; 80 | public bool readonly = false; 81 | public string? default_path = null; 82 | public DISTRIB_ID DISTR_ID=DISTRIB_ID.OTHER; 83 | public bool reduce_memory_usage = false; 84 | public bool force_debug = false; 85 | 86 | public signal void on_load(); 87 | 88 | public MySettings(string? cmd_conf_file=null,bool? standalone=false ){ 89 | this.typemap = new HashTable (str_hash, str_equal); 90 | if(standalone!=null) 91 | this.standalone_mode=standalone; 92 | 93 | if(cmd_conf_file!=null) 94 | this.conf_file = cmd_conf_file; 95 | else{ 96 | 97 | if(standalone!=null && this.standalone_mode==true) 98 | this.conf_file = GLib.Environment.get_user_config_dir()+"/altyo"+"/config-standalone.ini"; 99 | else 100 | this.conf_file = GLib.Environment.get_user_config_dir()+"/altyo"+"/config.ini"; 101 | } 102 | kf = new KeyFile(); 103 | this.load_config(); 104 | if(this.opened){ 105 | this.set_integer_list("profile_version",this.check_for_migrate(this.get_integer_list("profile_version", {0,0,0}, (ref new_val)=>{ 106 | if(new_val.length != 3){ 107 | new_val = {0,0,0}; 108 | return CFG_CHECK.REPLACE; 109 | } 110 | return CFG_CHECK.OK; 111 | })) ); 112 | /* some options related only for ubuntu, so to run same binary 113 | * try to guess linux distribution on which we are have runned, 114 | * guess only once, then save in config*/ 115 | string distr=this.get_string("distrib_id",""); 116 | if(distr==""){ 117 | distr=this.check_linux_distribution(); 118 | this.set_string("distrib_id",distr); 119 | } 120 | if(distr=="ubuntu") 121 | this.DISTR_ID=DISTRIB_ID.UBUNTU; 122 | 123 | this.reduce_memory_usage = this.get_boolean("reduce_memory_usage",false); 124 | } 125 | } 126 | 127 | public void load_config(){ 128 | debug("loading config..."); 129 | if(!GLib.FileUtils.test(this.conf_file,GLib.FileTest.EXISTS) ) 130 | GLib.DirUtils.create_with_parents(GLib.Path.get_dirname(this.conf_file),502);//755 131 | 132 | try { 133 | kf.load_from_file(this.conf_file, KeyFileFlags.KEEP_COMMENTS); 134 | this.opened = true; 135 | this.changed=false; 136 | this.on_load(); 137 | } catch (GLib.KeyFileError.PARSE err) { 138 | this.opened = true; 139 | this.changed=false; 140 | this.on_load(); 141 | } catch (KeyFileError err) { 142 | debug("Filed: kf.load_from_file"); 143 | warning (err.message); 144 | this.opened = false; 145 | } catch (FileError err) { 146 | //create default settings 147 | kf.set_string (this.profile, "custom_command", ""); 148 | /* 149 | * other settings will be filled on reation time 150 | */ 151 | var str = kf.to_data (null); 152 | try { 153 | FileUtils.set_contents (this.conf_file, str, str.length); 154 | this.opened = true; 155 | } catch (FileError err) { 156 | warning (err.message); 157 | } 158 | } 159 | } 160 | 161 | public void reload_config(){ 162 | this.on_load(); 163 | } 164 | 165 | public void save(bool force=false){ 166 | if(this.readonly==false){ 167 | if(this.changed || force){ 168 | var str = kf.to_data (null); 169 | try { 170 | debug("\tsave settings into file=%s\n",this.conf_file); 171 | FileUtils.set_contents (this.conf_file, str, str.length); 172 | } catch (FileError err) { 173 | warning (err.message); 174 | } 175 | } 176 | }else 177 | debug("config is read only, all changes will be lost!\n"); 178 | this.changed=false; 179 | } 180 | 181 | public void reset_to_defaults(){ 182 | var tmp=this.conf_file; 183 | this.conf_file+=".bak"; 184 | this.save(true);//save backup 185 | this.conf_file=tmp; 186 | try { 187 | debug("\treset_to_defaults settings file=%s\n",this.conf_file); 188 | FileUtils.set_contents (this.conf_file, "", 0); 189 | this.load_config(); 190 | } catch (FileError err) { 191 | warning (err.message); 192 | } 193 | } 194 | 195 | private int[] check_for_migrate(int[] version){ 196 | 197 | if(version[VER.major]==0 && version[VER.minor]==0){ 198 | version[VER.minor]=3;//update settings to latest version 0.3 199 | } 200 | 201 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<5){ 202 | /*migrate from 0.3 rc4 to rc5 203 | * move autostart file*/ 204 | string old_default_desktop_file=GLib.Environment.get_user_config_dir()+"/autostart/altyo.desktop"; 205 | string new_default_desktop_file=GLib.Environment.get_user_config_dir()+"/autostart/org.gtk.altyo.desktop"; 206 | 207 | if(GLib.FileUtils.test(old_default_desktop_file,GLib.FileTest.EXISTS) ) 208 | GLib.FileUtils.rename(old_default_desktop_file,new_default_desktop_file); 209 | 210 | version[VER.rc]=5;//update version 211 | } 212 | 213 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<6){ 214 | try { 215 | var old=kf.get_boolean(this.profile,"window_hide_after_close_last_tab"); 216 | if(old) 217 | kf.set_integer(this.profile,"window_action_on_close_last_tab",1);//restart shell and hide 218 | kf.remove_key(this.profile,"window_hide_after_close_last_tab"); 219 | this.changed=true; 220 | }catch (KeyFileError err) {} 221 | 222 | version[VER.rc]=6;//update version 223 | } 224 | 225 | /*if was 0.3.6 226 | * update program_style option, gtk prior 3.8 have memory leak when text-shadow is used. 227 | * */ 228 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<7){ 229 | if(Gtk.get_major_version()>=3 && Gtk.get_minor_version()<7){ 230 | try { 231 | string old=kf.get_string(this.profile,"program_style"); 232 | if(old!=null && old!="" ){ 233 | Regex regex = new Regex ("VTToggleButton\\:active \\{ text-shadow\\: 1px 1px 2px #005555\\;\\}"); 234 | try { 235 | string result = regex.replace(old,-1,0,""); 236 | kf.set_string(this.profile,"program_style",result); 237 | this.changed=true; 238 | }catch (RegexError e) { 239 | stdout.printf ("Error: %s\n", e.message); 240 | } 241 | kf.set_integer(this.profile,"window_action_on_close_last_tab",1);//restart shell and hide 242 | } 243 | }catch (KeyFileError err) {} 244 | } 245 | 246 | version[VER.rc]=7;//update version 247 | } 248 | 249 | /*if was 0.3.7 250 | * update program_style option, fix background for quick_options_notebook 251 | * */ 252 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<8){ 253 | try { 254 | string old=kf.get_string(this.profile,"program_style"); 255 | if(old!=null && old!="" ){ 256 | Regex regex = new Regex ("HVBox,#search_hbox\\{"); 257 | try { 258 | string result = regex.replace(old,-1,0,"HVBox,#quick_options_notebook {"); 259 | kf.set_string(this.profile,"program_style",result); 260 | this.changed=true; 261 | }catch (RegexError e) { 262 | stdout.printf ("Error: %s\n", e.message); 263 | } 264 | } 265 | }catch (KeyFileError err) {} 266 | version[VER.rc]=8;//update version 267 | } 268 | /*if was 0.3.8 269 | * now window position and size is unique for each monitor 270 | * */ 271 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<9){ 272 | try { 273 | string monitor=kf.get_string(this.profile,"window_default_monitor"); 274 | if(monitor!=null && monitor!=""){ 275 | kf.set_integer(this.profile,"terminal_width_%s".printf(monitor),kf.get_integer(this.profile,"terminal_width")); 276 | kf.set_integer(this.profile,"terminal_height_%s".printf(monitor),kf.get_integer(this.profile,"terminal_height")); 277 | kf.set_integer(this.profile,"window_position_y_%s".printf(monitor),kf.get_integer(this.profile,"window_position_y")); 278 | kf.set_integer(this.profile,"window_position_x_%s".printf(monitor),kf.get_integer(this.profile,"position")); 279 | } 280 | 281 | kf.remove_key(this.profile,"terminal_height"); 282 | kf.remove_key(this.profile,"terminal_width"); 283 | kf.remove_key(this.profile,"window_position_y"); 284 | kf.remove_key(this.profile,"position"); 285 | }catch (KeyFileError err) {} 286 | 287 | version[VER.rc]=9;//update version 288 | } 289 | /*if was 0.3.9 290 | * update program_style option, fix background for settings tab 291 | * */ 292 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<10){ 293 | try { 294 | string old=kf.get_string(this.profile,"program_style"); 295 | if(old!=null && old!="" ){ 296 | kf.set_string(this.profile,"program_style",old+" #settings-scrolledwindow{ background-color: @bg_color;} "); 297 | } 298 | }catch (KeyFileError err) {} 299 | version[VER.rc]=10;//update version 300 | } 301 | /*if was 0.3.10 302 | * update program_style option, remove button shadow, disable animation 303 | * */ 304 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<11){ 305 | try { 306 | string old=kf.get_string(this.profile,"program_style"); 307 | if(old!=null && old!="" ){ 308 | Regex regex = new Regex ("#tasks_notebook"); 309 | try { 310 | string result = regex.replace(old,-1,0,".window_multitabs"); 311 | old=result; 312 | }catch (RegexError e) { 313 | stdout.printf ("Error: %s\n", e.message); 314 | } 315 | 316 | kf.set_string(this.profile,"program_style",old+" VTToggleButton{ box-shadow: none;"+((Gtk.get_major_version()>=3 && Gtk.get_minor_version()>4)?"transition-duration: 0s;":"")+"} .window_single_tab {border-width: 2px 2px 2px 2px;border-color: #3C3B37;border-style: solid;}"); 317 | } 318 | }catch (KeyFileError err) {} 319 | version[VER.rc]=11;//update version 320 | } 321 | /*if was 0.3.11 322 | * update program_style option, new theme handling 323 | * */ 324 | if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<12){ 325 | try { 326 | string old=kf.get_string(this.profile,"program_style"); 327 | if(old!=null && old!="" ){ 328 | kf.remove_key(this.profile,"program_style"); 329 | kf.remove_key(this.profile,"tab_title_format"); 330 | kf.remove_key(this.profile,"tab_title_format_regex"); 331 | } 332 | }catch (KeyFileError err) {} 333 | version[VER.rc]=12;//update version 334 | } 335 | return version; 336 | } 337 | 338 | private string check_linux_distribution(){ 339 | string contents; 340 | size_t length; 341 | if( GLib.FileUtils.test("/etc/lsb-release",GLib.FileTest.EXISTS) ){ 342 | try{ 343 | GLib.FileUtils.get_contents("/etc/lsb-release",out contents,out length); 344 | if(length>1 && Regex.match_simple(".*ubuntu.*",contents,GLib.RegexCompileFlags.CASELESS|GLib.RegexCompileFlags.MULTILINE)){ 345 | return "ubuntu"; 346 | } 347 | } catch (FileError err) { 348 | } 349 | }else 350 | if( GLib.FileUtils.test("/etc/issue",GLib.FileTest.EXISTS) ){ 351 | try{ 352 | GLib.FileUtils.get_contents("/etc/issue",out contents,out length); 353 | if(length>1 && Regex.match_simple(".*ubuntu.*",contents,GLib.RegexCompileFlags.CASELESS|GLib.RegexCompileFlags.MULTILINE)){ 354 | return "ubuntu"; 355 | } 356 | } catch (FileError err) { 357 | } 358 | } 359 | return "other"; 360 | } 361 | 362 | public bool get_boolean (string key,bool? def,check_boolean? check_cb=null){ 363 | int key_type; 364 | if(!this.typemap.lookup_extended(key,null,out key_type)) 365 | this.typemap.insert(key,(int)CFG_TYPE.TYPE_BOOLEAN); 366 | else if(key_type!=CFG_TYPE.TYPE_BOOLEAN) 367 | GLib.assert(key_type==CFG_TYPE.TYPE_BOOLEAN); 368 | 369 | bool ret = def; 370 | try { 371 | ret = kf.get_boolean(this.profile,key); 372 | if(check_cb!=null) 373 | switch(check_cb(ref ret)){ 374 | case CFG_CHECK.REPLACE: 375 | this.changed=true; 376 | kf.set_boolean(this.profile,key,ret); 377 | break; 378 | case CFG_CHECK.USE_DEFAULT: 379 | ret=def; 380 | this.changed=true; 381 | kf.set_boolean(this.profile,key,def); 382 | break; 383 | } 384 | } catch (KeyFileError err) { 385 | warning (err.message); 386 | this.changed=true; 387 | kf.set_boolean(this.profile,key,def); 388 | ret = def; 389 | } 390 | return ret; 391 | } 392 | 393 | public int get_integer (string key,int def,check_integer? check_cb=null){ 394 | int key_type; 395 | if(!this.typemap.lookup_extended(key,null,out key_type)) 396 | this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER); 397 | else if(key_type!=CFG_TYPE.TYPE_INTEGER) 398 | GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER); 399 | 400 | int ret = def; 401 | try { 402 | ret = kf.get_integer(this.profile,key); 403 | if(check_cb!=null) 404 | switch(check_cb(ref ret)){ 405 | case CFG_CHECK.REPLACE: 406 | this.changed=true; 407 | kf.set_integer(this.profile,key,ret); 408 | break; 409 | case CFG_CHECK.USE_DEFAULT: 410 | ret=def; 411 | this.changed=true; 412 | kf.set_integer(this.profile,key,def); 413 | break; 414 | } 415 | } catch (KeyFileError err) { 416 | warning (err.message); 417 | this.changed=true; 418 | kf.set_integer(this.profile,key,def); 419 | ret = def; 420 | } 421 | return ret; 422 | } 423 | 424 | public int[] get_integer_list (string key,int[] def,check_integer_list? check_cb=null){ 425 | int key_type; 426 | if(!this.typemap.lookup_extended(key,null,out key_type)) 427 | this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER_LIST); 428 | else if(key_type!=CFG_TYPE.TYPE_INTEGER_LIST) 429 | GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER_LIST); 430 | 431 | int[] ret = def; 432 | try { 433 | ret = kf.get_integer_list(this.profile,key); 434 | if(check_cb!=null) 435 | switch(check_cb(ref ret)){ 436 | case CFG_CHECK.REPLACE: 437 | this.changed=true; 438 | kf.set_integer_list(this.profile,key,ret); 439 | break; 440 | case CFG_CHECK.USE_DEFAULT: 441 | ret=def; 442 | this.changed=true; 443 | kf.set_integer_list(this.profile,key,def); 444 | break; 445 | } 446 | } catch (KeyFileError err) { 447 | warning (err.message); 448 | this.changed=true; 449 | kf.set_integer_list(this.profile,key,def); 450 | ret = def; 451 | } 452 | return ret; 453 | } 454 | 455 | public double get_double (string key,double def,check_double? check_cb=null){ 456 | int key_type; 457 | if(!this.typemap.lookup_extended(key,null,out key_type)) 458 | this.typemap.insert(key,CFG_TYPE.TYPE_DOUBLE); 459 | else if(key_type!=CFG_TYPE.TYPE_DOUBLE) 460 | GLib.assert(key_type==CFG_TYPE.TYPE_DOUBLE); 461 | 462 | double ret = def; 463 | try { 464 | ret = kf.get_double(this.profile,key); 465 | if(check_cb!=null) 466 | switch(check_cb(ref ret)){ 467 | case CFG_CHECK.REPLACE: 468 | this.changed=true; 469 | kf.set_double(this.profile,key,ret); 470 | break; 471 | case CFG_CHECK.USE_DEFAULT: 472 | ret=def; 473 | this.changed=true; 474 | kf.set_double(this.profile,key,def); 475 | break; 476 | } 477 | } catch (KeyFileError err) { 478 | warning (err.message); 479 | this.changed=true; 480 | kf.set_double(this.profile,key,def); 481 | ret = def; 482 | } 483 | return ret; 484 | } 485 | 486 | public string[] get_string_list (string key, string[] def,check_string_list? check_cb=null) { 487 | int key_type; 488 | if(!this.typemap.lookup_extended(key,null,out key_type)) 489 | this.typemap.insert(key,CFG_TYPE.TYPE_STRING_LIST); 490 | else if(key_type!=CFG_TYPE.TYPE_STRING_LIST) 491 | GLib.assert(key_type==CFG_TYPE.TYPE_STRING_LIST); 492 | 493 | string[] ret = def; 494 | try { 495 | ret = kf.get_string_list(this.profile,key); 496 | if(check_cb!=null) 497 | switch(check_cb(ref ret)){ 498 | case CFG_CHECK.REPLACE: 499 | this.changed=true; 500 | kf.set_string_list(this.profile,key,ret); 501 | break; 502 | case CFG_CHECK.USE_DEFAULT: 503 | ret=def; 504 | this.changed=true; 505 | kf.set_string_list(this.profile,key,def); 506 | break; 507 | } 508 | } catch (KeyFileError err) { 509 | warning (err.message); 510 | this.changed=true; 511 | kf.set_string_list(this.profile,key,def); 512 | ret = def; 513 | } 514 | return ret; 515 | } 516 | 517 | public string? get_string(string key, string def,check_string? check_cb=null) { 518 | int key_type; 519 | if(!this.typemap.lookup_extended(key,null,out key_type)) 520 | this.typemap.insert(key,CFG_TYPE.TYPE_STRING); 521 | else if(key_type!=CFG_TYPE.TYPE_STRING) 522 | GLib.assert(key_type==CFG_TYPE.TYPE_STRING); 523 | 524 | string ret = def; 525 | try { 526 | ret = kf.get_string(this.profile,key); 527 | if(check_cb!=null) 528 | switch(check_cb(ref ret)){ 529 | case CFG_CHECK.REPLACE: 530 | this.changed=true; 531 | kf.set_string(this.profile,key,ret); 532 | break; 533 | case CFG_CHECK.USE_DEFAULT: 534 | ret=def; 535 | this.changed=true; 536 | kf.set_string(this.profile,key,def); 537 | break; 538 | } 539 | } catch (KeyFileError err) { 540 | warning (err.message); 541 | this.changed=true; 542 | kf.set_string(this.profile,key,def); 543 | ret = def; 544 | } 545 | return ret;//can be null 546 | } 547 | 548 | 549 | public bool set_string_list (string key, string[] def) { 550 | int key_type; 551 | if(!this.typemap.lookup_extended(key,null,out key_type)) 552 | this.typemap.insert(key,CFG_TYPE.TYPE_STRING_LIST); 553 | else if(key_type!=CFG_TYPE.TYPE_STRING_LIST) 554 | GLib.assert(key_type==CFG_TYPE.TYPE_STRING_LIST); 555 | 556 | bool ret = true; 557 | try { 558 | this.changed=true; 559 | kf.set_string_list(this.profile,key,def); 560 | } catch (KeyFileError err) { 561 | warning (err.message); 562 | ret = false; 563 | } 564 | return ret; 565 | } 566 | 567 | public bool set_string(string key, string? def) { 568 | int key_type; 569 | if(!this.typemap.lookup_extended(key,null,out key_type)) 570 | this.typemap.insert(key,CFG_TYPE.TYPE_STRING); 571 | else if(key_type!=CFG_TYPE.TYPE_STRING) 572 | GLib.assert(key_type==CFG_TYPE.TYPE_STRING); 573 | 574 | bool ret = true; 575 | try { 576 | this.changed=true; 577 | if(def==null) 578 | kf.set_string(this.profile,key,""); 579 | else 580 | kf.set_string(this.profile,key,def); 581 | } catch (KeyFileError err) { 582 | warning (err.message); 583 | ret = false; 584 | } 585 | return ret; 586 | } 587 | 588 | public bool set_integer (string key,int def){ 589 | int key_type; 590 | if(!this.typemap.lookup_extended(key,null,out key_type)) 591 | this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER); 592 | else if(key_type!=CFG_TYPE.TYPE_INTEGER) 593 | GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER); 594 | 595 | bool ret = true; 596 | try { 597 | this.changed=true; 598 | kf.set_integer(this.profile,key,def); 599 | } catch (KeyFileError err) { 600 | warning (err.message); 601 | ret = false; 602 | } 603 | return ret; 604 | } 605 | 606 | public bool set_integer_list (string key,int[] def){ 607 | int key_type; 608 | if(!this.typemap.lookup_extended(key,null,out key_type)) 609 | this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER_LIST); 610 | else if(key_type!=CFG_TYPE.TYPE_INTEGER_LIST) 611 | GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER_LIST); 612 | 613 | bool ret = true; 614 | try { 615 | this.changed=true; 616 | kf.set_integer_list(this.profile,key,def); 617 | } catch (KeyFileError err) { 618 | warning (err.message); 619 | ret = false; 620 | } 621 | return ret; 622 | } 623 | 624 | public bool set_boolean (string key,bool def){ 625 | int key_type; 626 | if(!this.typemap.lookup_extended(key,null,out key_type)) 627 | this.typemap.insert(key,CFG_TYPE.TYPE_BOOLEAN); 628 | else if(key_type!=CFG_TYPE.TYPE_BOOLEAN) 629 | GLib.assert(key_type==CFG_TYPE.TYPE_BOOLEAN); 630 | 631 | bool ret = true; 632 | try { 633 | this.changed=true; 634 | kf.set_boolean(this.profile,key,def); 635 | } catch (KeyFileError err) { 636 | warning (err.message); 637 | ret = false; 638 | } 639 | return ret; 640 | } 641 | 642 | public bool set_double (string key,double def,uint digits_after_comma){ 643 | int key_type; 644 | if(!this.typemap.lookup_extended(key,null,out key_type)) 645 | this.typemap.insert(key,CFG_TYPE.TYPE_DOUBLE); 646 | else if(key_type!=CFG_TYPE.TYPE_DOUBLE) 647 | GLib.assert(key_type==CFG_TYPE.TYPE_DOUBLE); 648 | 649 | bool ret = true; 650 | try { 651 | this.changed=true; 652 | if(digits_after_comma>0){ 653 | string S="%.2f".printf(round_double(def,digits_after_comma)); 654 | //printf string is localized, but KeyFile allow only 655 | //dot as digits delimeter in double, 656 | //so replace comma with dot 657 | //is there better solution? 658 | S=S.replace(",","."); 659 | debug("set_double=%s",S); 660 | kf.set_string(this.profile,key,S); 661 | }else{ 662 | kf.set_double(this.profile,key,def); 663 | } 664 | } catch (KeyFileError err) { 665 | warning (err.message); 666 | ret = false; 667 | } 668 | return ret; 669 | } 670 | 671 | public string get_accel_string(string key, string def,check_string? check_cb=null) { 672 | int key_type; 673 | if(!this.typemap.lookup_extended(key,null,out key_type)) 674 | this.typemap.insert(key,CFG_TYPE.TYPE_ACCEL_STRING); 675 | else if(key_type!=CFG_TYPE.TYPE_ACCEL_STRING) 676 | GLib.assert(key_type==CFG_TYPE.TYPE_ACCEL_STRING); 677 | 678 | string ret = def; 679 | try { 680 | ret = kf.get_string(this.accel_section,key); 681 | } catch (KeyFileError err) { 682 | warning (err.message); 683 | this.changed=true; 684 | kf.set_string(this.accel_section,key,def); 685 | ret = def; 686 | } 687 | return ret; 688 | } 689 | 690 | public bool set_accel_string(string key, string def) { 691 | int key_type; 692 | if(!this.typemap.lookup_extended(key,null,out key_type)) 693 | this.typemap.insert(key,CFG_TYPE.TYPE_ACCEL_STRING); 694 | else if(key_type!=CFG_TYPE.TYPE_ACCEL_STRING) 695 | GLib.assert(key_type==CFG_TYPE.TYPE_ACCEL_STRING); 696 | 697 | bool ret = true; 698 | try { 699 | this.changed=true; 700 | kf.set_string(this.accel_section,key,def); 701 | } catch (KeyFileError err) { 702 | warning (err.message); 703 | ret = false; 704 | } 705 | return ret; 706 | } 707 | 708 | public string[] get_qconnection_list () { 709 | string[] ret = {}; 710 | if(kf.has_group(this.qconnection_section)){ 711 | try { 712 | ret = kf.get_keys(this.qconnection_section); 713 | } catch (KeyFileError err) { 714 | warning (err.message); 715 | this.changed=true; 716 | //if(err.code == GLib.KeyFileError.GROUP_NOT_FOUND) 717 | kf.set_string(this.qconnection_section,null,""); 718 | ret = {}; 719 | } 720 | } 721 | return ret; 722 | } 723 | 724 | public string[] get_qconnection_data_list (string key) { 725 | string[] ret = {}; 726 | try { 727 | ret = kf.get_string_list(this.qconnection_section,key); 728 | } catch (KeyFileError err) { 729 | warning (err.message); 730 | //kf.set_string_list(this.qconnection_section,key,{}); 731 | ret = {}; 732 | } 733 | return ret; 734 | } 735 | 736 | public string[] get_profile_keys (){ 737 | return this.kf.get_keys (this.profile); 738 | } 739 | 740 | public CFG_TYPE get_key_type(string key){ 741 | int key_type; 742 | if(this.typemap.lookup_extended(key,null,out key_type)){ 743 | return (CFG_TYPE)key_type; 744 | }else{ 745 | debug("get_key_type TYPE_UNKNOWN for key=%s",key); 746 | return CFG_TYPE.TYPE_UNKNOWN; 747 | } 748 | } 749 | 750 | public bool check_markup(string pattern,out string err_text){ 751 | bool ret=true; 752 | Pango.AttrList attr_list; 753 | string text; 754 | unichar accel_char; 755 | try { 756 | Pango.parse_markup(pattern,-1,(unichar)"_",out attr_list, out text, out accel_char); 757 | } catch( Error re ) { 758 | ret=false; 759 | debug("check_markup err:%s",re.message); 760 | err_text=re.message; 761 | } 762 | return ret; 763 | } 764 | 765 | public bool check_regex(string pattern,out string err_text){ 766 | bool ret=true; 767 | try { 768 | var regex = new Regex( pattern, RegexCompileFlags.EXTENDED ); 769 | } catch( RegexError re ) { 770 | ret=false; 771 | debug("check_regex err:%s",re.message); 772 | err_text=re.message; 773 | } 774 | return ret; 775 | } 776 | /* todo 777 | public get_boolean_list 778 | public get_comment 779 | public get_double 780 | public get_double_list 781 | public get_groups 782 | public get_int64 783 | public get_integer 784 | public get_integer_list 785 | public get_keys 786 | public get_locale_string 787 | public get_locale_string_list 788 | public get_start_group 789 | public get_string 790 | public get_string_list 791 | public get_uint64 792 | public get_value 793 | public has_group 794 | public has_key 795 | public load_from_data 796 | public load_from_data_dirs 797 | public load_from_dirs 798 | public load_from_file 799 | public remove_comment 800 | public remove_group 801 | public remove_key 802 | public set_boolean 803 | public set_boolean_list 804 | public set_comment 805 | public set_double 806 | public set_double_list 807 | public set_int64 808 | public set_integer 809 | public set_integer_list 810 | public set_list_separator 811 | public set_locale_string 812 | public set_locale_string_list 813 | public set_string 814 | public set_string_list 815 | public set_uint64 816 | public set_value 817 | public to_data 818 | */ 819 | } 820 | 821 | public string hexRGBA(Gdk.RGBA c){ 822 | //output #AABBCC 823 | return "#%02hhX%02hhX%02hhX".printf((char)((int)(c.red*255)),(char)((int)(c.green*255)),(char)((int)(c.blue*255))); 824 | } 825 | 826 | public double round_double(double def,uint digits_after_comma){ 827 | uint round=1; 828 | double rest=5.0; 829 | while(digits_after_comma-->0){ 830 | round*=10; 831 | } 832 | rest/=(round*10); 833 | int i=(int)((def+rest) * round);//round 834 | def=(double)((double)(i)/(double)round); 835 | return def; 836 | } 837 | 838 | extern void gtk_style_context_get_style_property (Gtk.StyleContext context, 839 | string property_name, 840 | ref Value value); 841 | public string replace_color_in_markup(Widget w,string markup,StateFlags state=Gtk.StateFlags.NORMAL){ 842 | Regex regex = new Regex ("""(foreground\=['"]\s*(?P[^'"]+)\s*['"])|(background\=['"]\s*(?P[^'"]+)\s*['"])"""); 843 | int offset=0; 844 | var ret = regex.replace_eval(markup,-1,0,0, (match_info, result)=>{ 845 | int start_pos, end_pos; 846 | string? name; 847 | unowned Gdk.RGBA? tmp=null; 848 | name = match_info.fetch_named("foreground"); 849 | if(name!=null){ 850 | if(name.get_char(0)!='#'){//if color is css color name 851 | //try to guess 852 | Gdk.RGBA? color=null; 853 | GLib.ParamSpec? prop = w.find_style_property(name); 854 | if(prop!=null){ 855 | var context = w.get_style_context(); 856 | var old=context.get_state(); 857 | context.set_state(state); 858 | var val = new Value(typeof(Gdk.RGBA)); 859 | //vala bug, vala binding for gtk_style_context_get_style_property is broken 860 | //context.get_style_property(name,val); 861 | gtk_style_context_get_style_property(context,name,ref val); 862 | if(val.get_boxed()!=null) 863 | color=*(Gdk.RGBA*)val.get_boxed(); 864 | context.set_state(old); 865 | //~ w.style_get(name,out tmp); 866 | //~ color=tmp; 867 | //~ tmp.free(); 868 | } 869 | #if VALA_0_17 870 | if(color!=null || w.get_style_context().lookup_color(name,out color) ){ 871 | #else 872 | if(color!=null || vala_016_style_context_lookup_color(w.get_style_context(),name,out color) ){ 873 | #endif 874 | result.append("foreground='"); 875 | result.append(hexRGBA(color)); 876 | result.append("'"); 877 | }else 878 | debug("markup: wrong color '%s', foreground will be ignored",name); 879 | }else 880 | result.append(match_info.fetch(0)); 881 | }else{ 882 | name = match_info.fetch_named("background"); 883 | 884 | if(name!=null){ 885 | if(name.get_char(0)!='#'){//if color is css color name 886 | Gdk.RGBA? color=null; 887 | GLib.ParamSpec? prop = w.find_style_property(name); 888 | if(prop!=null){ 889 | var context = w.get_style_context(); 890 | var old=context.get_state(); 891 | context.set_state(state); 892 | var val = new Value(typeof(Gdk.RGBA)); 893 | //vala bug, vala binding for gtk_style_context_get_style_property is broken 894 | //context.get_style_property(name,val); 895 | gtk_style_context_get_style_property(context,name,ref val); 896 | if(val.get_boxed()!=null) 897 | color=*(Gdk.RGBA*)val.get_boxed(); 898 | context.set_state(old); 899 | //~ w.style_get(name,out color); 900 | //~ color=tmp; 901 | //~ tmp.free(); 902 | } 903 | #if VALA_0_17 904 | if(color!=null || w.get_style_context().lookup_color(name,out color) ){ 905 | #else 906 | if(color!=null || vala_016_style_context_lookup_color(w.get_style_context(),name,out color) ){ 907 | #endif 908 | result.append("background='"); 909 | result.append(hexRGBA(color)); 910 | result.append("'"); 911 | }else 912 | debug("markup: wrong color '%s', background will be ignored",name); 913 | }else 914 | result.append(match_info.fetch(0)); 915 | }else 916 | result.append(match_info.fetch(0)); 917 | } 918 | return false; 919 | });//while 920 | return ret; 921 | }//replace_color_in_markup 922 | -------------------------------------------------------------------------------- /altyo_hotkey.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | using Gtk; 19 | using Gdk; 20 | 21 | // Based on http://code.valaide.org/content/global-hotkeys by Oliver Sauder 22 | 23 | /*public static void static_handler (string a) { 24 | PanelHotkey.instance().triggered (a); 25 | }*/ 26 | 27 | public class KeyBinding : Object { 28 | public string combination; 29 | public uint key_code; 30 | public uint modifiers; 31 | public bool relesed {get;set;default=true;} 32 | public signal void on_trigged(); 33 | 34 | public KeyBinding (string combination, uint key_code, uint modifiers) { 35 | this.combination = combination; 36 | this.key_code = key_code; 37 | this.modifiers = modifiers; 38 | } 39 | 40 | ~KeyBinding(){ 41 | debug("~KeyBinding"); 42 | //free(this.combination); 43 | } 44 | } 45 | 46 | public class PanelHotkey : Object { 47 | public signal void triggered (string combination); 48 | public uint32 last_key_event_time {get;set;default =0;} 49 | public uint32 last_property_event_time {get;set;default =0;} 50 | private unowned X.Display display; 51 | private Gdk.Window root_window; 52 | private X.ID x_id; 53 | private X.Atom active_window; 54 | private bool processing_event = false; 55 | public signal void on_active_window_change(); 56 | 57 | private static uint[] lock_modifiers = { 58 | 0, 59 | Gdk.ModifierType.MOD2_MASK, // NUM_LOCK 60 | Gdk.ModifierType.LOCK_MASK, // CAPS_LOCK 61 | Gdk.ModifierType.MOD5_MASK, // SCROLL_LOCK 62 | Gdk.ModifierType.MOD2_MASK|Gdk.ModifierType.LOCK_MASK, 63 | Gdk.ModifierType.MOD2_MASK|Gdk.ModifierType.MOD5_MASK, 64 | Gdk.ModifierType.LOCK_MASK|Gdk.ModifierType.MOD5_MASK, 65 | Gdk.ModifierType.MOD2_MASK|Gdk.ModifierType.LOCK_MASK|Gdk.ModifierType.MOD5_MASK 66 | }; 67 | 68 | private GLib.List bindings; 69 | 70 | public PanelHotkey () { 71 | bindings = new GLib.List (); 72 | root_window = get_default_root_window (); 73 | 74 | this.display = Gdk.x11_get_default_xdisplay (); 75 | this.active_window = this.display.intern_atom("_NET_ACTIVE_WINDOW",false); 76 | x_id = X11Window.get_xid (root_window); 77 | root_window.add_filter (event_filter); 78 | 79 | } 80 | 81 | ~PanelHotkey () { 82 | debug("~PanelHotkey ()"); 83 | this.unbind(); 84 | var root_window = Gdk.get_default_root_window (); 85 | root_window.remove_filter(event_filter); 86 | } 87 | 88 | public Gdk.FilterReturn event_filter (Gdk.XEvent gxevent, Gdk.Event event) { 89 | 90 | FilterReturn filter = FilterReturn.CONTINUE; 91 | this.processing_event = true; 92 | void* p = gxevent; 93 | X.Event* xevent = (X.Event*) p; 94 | this.last_key_event_time = (uint32)xevent->xkey.time; 95 | 96 | if (xevent->type == X.EventType.KeyPress) { 97 | foreach (var binding in bindings) { 98 | if (binding.relesed == true && xevent->xkey.keycode == binding.key_code && 99 | (xevent->xkey.state & ~ (lock_modifiers[7])) == binding.modifiers) { 100 | binding.relesed=false; 101 | binding.on_trigged(); 102 | } 103 | } 104 | }else if (xevent->type == X.EventType.KeyRelease ){ 105 | foreach (var binding in bindings) { 106 | if (xevent->xkey.keycode == binding.key_code && 107 | (xevent->xkey.state & ~ (lock_modifiers[7])) == binding.modifiers) { 108 | binding.relesed=true;//to ignore AutoRepeat 109 | } 110 | } 111 | } else if (xevent->type == X.EventType.PropertyNotify ) { 112 | X.PropertyEvent* pevent = (X.PropertyEvent*) p; 113 | if(pevent->atom == this.active_window){//_NET_ACTIVE_WINDOW usual come after focus change 114 | this.last_property_event_time=(uint32)pevent->time; 115 | this.on_active_window_change(); 116 | } 117 | //debug("event_filter type=%d state=%d window=%d atom=%s",(int)pevent->type,(int)pevent->state,(int)pevent->window,this.display.get_atom_name(pevent->atom)); 118 | } 119 | this.processing_event = false; 120 | return filter; 121 | } 122 | 123 | public KeyBinding bind (string combination) { 124 | bool error = false; 125 | uint key_sym; 126 | ModifierType modifiers; 127 | 128 | if(this.display==null){ 129 | debug("error: KeyBinding display==null"); 130 | return null; 131 | } 132 | 133 | accelerator_parse (combination, out key_sym, out modifiers); 134 | debug("bind %s display=%d key_sym=%d modifiers=%d",combination,(int)display,(int)key_sym,modifiers); 135 | if(key_sym != 0 && (combination.contains(">") == (modifiers!=0?true:false) ) ){ 136 | var key_code = display.keysym_to_keycode ((ulong)key_sym); 137 | 138 | if (key_code != 0) { 139 | 140 | 141 | foreach (var mod in lock_modifiers){ 142 | error_trap_push (); 143 | this.display.grab_key (key_code, modifiers | mod, x_id, false, X.GrabMode.Async, X.GrabMode.Async); 144 | flush(); 145 | if (error_trap_pop()>0) { 146 | this.display.ungrab_key (key_code, modifiers | mod, x_id); 147 | error=true; 148 | } 149 | } 150 | if(!error){ 151 | var binding = new KeyBinding (combination, key_code, modifiers); 152 | if(bindings.first()!=null) 153 | bindings.append(binding); 154 | else 155 | bindings.prepend(binding); 156 | return binding; 157 | } 158 | } 159 | } 160 | debug ("Binding '%s' failed!\n", combination); 161 | return null; 162 | } 163 | 164 | public void unbind(){ 165 | foreach(unowned KeyBinding bind in bindings){ 166 | foreach (var mod in lock_modifiers){ 167 | this.display.ungrab_key ((int)bind.key_code, bind.modifiers | mod, x_id); 168 | flush(); 169 | } 170 | bindings.remove(bind); 171 | bind.unref();//destroy 172 | } 173 | } 174 | 175 | /* comment from tilda source, key_grabber.c 176 | * Shamelessly adapted (read: ripped off) from gdk_window_focus() and 177 | * http://code.google.com/p/ttm/ trunk/src/window.c set_active() 178 | * 179 | * Also, more thanks to halfline and marnanel from irc.gnome.org #gnome 180 | * for their help in figuring this out. 181 | * 182 | * Thank you. And boo to metacity, because they keep breaking us. 183 | */ 184 | public void send_net_active_window(Gdk.Window window){ 185 | 186 | if(window==null) 187 | return; 188 | 189 | var t = Gdk.x11_get_server_time(window); 190 | window.focus(t); 191 | 192 | //~ var event = X.ClientMessageEvent (); 193 | //~ event.type = X.EventType.ClientMessage; 194 | //~ event.serial = 0; 195 | //~ event.send_event = true; 196 | //~ event.display = Gdk.x11_get_default_xdisplay (); //this.display; 197 | //~ event.window = Gdk.X11Window.get_xid(window);//send altyo window id 198 | //~ event.message_type = x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); 199 | //~ event.format = 32; 200 | //~ event.data.l [0] = 2; 201 | //~ event.data.l [1] = Gtk.get_current_event_time();//(this.processing_event == true ? this.last_event_time : Gdk.CURRENT_TIME); 202 | //~ event.data.l [2] = 0; 203 | //~ event.data.l [3] = 0; 204 | //~ event.data.l [4] = 0; 205 | //~ X.Event e = (X.Event) event; 206 | //~ 207 | //~ display.send_event (Gdk.x11_get_default_root_xwindow(), false, X.EventMask.SubstructureRedirectMask|X.EventMask.StructureNotifyMask, ref e); 208 | 209 | } 210 | public X.Window get_input_focus(){ 211 | int revert_to_return; 212 | X.Window w,root_return; 213 | X.Window root_xwin=Gdk.X11Window.get_xid(this.root_window); 214 | 215 | this.display.get_input_focus(out w, out revert_to_return); 216 | //debug("get_input_focus=%x revert_to_return=%d",(int)w,revert_to_return); 217 | if(w>1){//not None, not PointerRoot, see XGetInputFocus 218 | do{ 219 | X.Window parent_return; 220 | X.Window[] children_return; 221 | X.Atom[] protocols=null; 222 | this.display.query_tree (w, out root_return, out parent_return, out children_return); 223 | //debug("get_input_focus=%x",(int)parent_return); 224 | 225 | if(parent_return>1){ 226 | this.display.get_wm_protocols(parent_return,out protocols); 227 | if(parent_return != root_xwin && protocols != null) 228 | w=parent_return; 229 | else 230 | break; 231 | }else 232 | break; 233 | }while(true); 234 | } 235 | return w; 236 | } 237 | 238 | public X.Window get_transient_for_xid(X.Window w){ 239 | X.Window result; 240 | this.display.get_transient_for_hint(w,out result); 241 | return result; 242 | } 243 | 244 | } 245 | -------------------------------------------------------------------------------- /altyo_myoverlaybox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | /* 19 | * Custom implementation of GtkOverlay 20 | * author: Konstantinov Denis 21 | * 22 | * */ 23 | 24 | using Gtk; 25 | 26 | public class MyOverlayBox : Bin { 27 | private Widget main_widget=null; 28 | private Widget overlay_widget=null; 29 | 30 | public MyOverlayBox(){ 31 | //this.set_has_window (false); 32 | } 33 | 34 | public override void add (Widget w){ 35 | if(main_widget==null){ 36 | w.set_parent(this); 37 | main_widget=w; 38 | w.show(); 39 | } 40 | } 41 | 42 | public void add_overlay (Widget w){ 43 | if(overlay_widget==null){ 44 | w.set_parent(this); 45 | overlay_widget=w; 46 | } 47 | } 48 | 49 | public override SizeRequestMode get_request_mode () { 50 | return (Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH); 51 | } 52 | 53 | public override void get_preferred_width (out int o_minimum_width, out int o_natural_width) { 54 | var nat = 0; 55 | var min = 0; 56 | if(main_widget!=null) 57 | main_widget.get_preferred_width (out min, out nat); 58 | 59 | o_minimum_width=int.max(o_minimum_width,min); 60 | o_natural_width=int.max(o_natural_width,nat); 61 | 62 | if(overlay_widget!=null) 63 | overlay_widget.get_preferred_width (out min, out nat); 64 | //~Ignore overlay_widget size 65 | //~ o_minimum_width=int.max(o_minimum_width,min); 66 | //~ o_natural_width=int.max(o_natural_width,nat); 67 | } 68 | 69 | public override void get_preferred_height_for_width (int width,out int minimum_height, out int natural_height) { 70 | var nat = 0; 71 | var min = 0; 72 | if(main_widget!=null) 73 | main_widget.get_preferred_height_for_width (width,out min, out nat); 74 | 75 | minimum_height=int.max(minimum_height,min); 76 | natural_height=int.max(natural_height,nat); 77 | 78 | if(overlay_widget!=null) 79 | overlay_widget.get_preferred_height_for_width (width,out min, out nat); 80 | //~Ignore overlay_widget size 81 | //~ minimum_height=int.max(minimum_height,min); 82 | //~ natural_height=int.max(natural_height,nat); 83 | } 84 | 85 | public override void size_allocate (Gtk.Allocation allocation) { 86 | base.size_allocate (allocation);//allocate container it self 87 | 88 | if(main_widget!=null) 89 | main_widget.size_allocate(allocation); 90 | 91 | if(overlay_widget!=null){ 92 | allocation.x+=0; 93 | allocation.y+=0; 94 | //setup same size as main_widget no variants 95 | overlay_widget.set_size_request(allocation.width,allocation.height); 96 | overlay_widget.size_allocate(allocation); 97 | } 98 | 99 | } 100 | 101 | public override void forall_internal(bool include_internal,Gtk.Callback callback){ 102 | if(main_widget!=null && main_widget.parent==this) 103 | callback(main_widget); 104 | if(overlay_widget!=null && overlay_widget.parent==this) 105 | callback(overlay_widget); 106 | } 107 | 108 | public override void remove (Widget widget){ 109 | widget.unparent(); 110 | } 111 | 112 | public override void map () { 113 | //first present overlay_widget , otherwise overlay_widget will be behind main_widget! 114 | if(this.overlay_widget.visible) 115 | this.overlay_widget.map(); 116 | base.map(); 117 | } 118 | 119 | public override void realize () { 120 | debug("realize"); 121 | 122 | /*var attributes = new Gdk.WindowAttr(); 123 | int attributes_mask; 124 | Gtk.Allocation allocation; 125 | 126 | this.get_allocation (out allocation); 127 | 128 | attributes.window_type = Gdk.WindowType.CHILD; 129 | attributes.wclass = Gdk.WindowWindowClass.OUTPUT; 130 | attributes.width = allocation.width; 131 | attributes.height = allocation.height; 132 | attributes.x = allocation.x; 133 | attributes.y = allocation.y; 134 | attributes_mask = Gdk.WindowAttributesType.X | Gdk.WindowAttributesType.Y; 135 | attributes.event_mask = this.get_events () | Gdk.EventMask.EXPOSURE_MASK; 136 | 137 | var window = new Gdk.Window (this.get_window (), 138 | attributes, attributes_mask); 139 | 140 | //dialog_vbox.set_window (vtw.get_window()); 141 | this.set_window (window); 142 | //this.set_has_window (true);*/ 143 | 144 | debug("before base realize"); 145 | base.realize(); 146 | debug("after base realize"); 147 | 148 | var attributes = Gdk.WindowAttr(); 149 | int attributes_mask; 150 | Gtk.Allocation allocation; 151 | 152 | overlay_widget.get_allocation (out allocation); 153 | 154 | attributes.window_type = Gdk.WindowType.CHILD; 155 | attributes.wclass = Gdk.WindowWindowClass.INPUT_OUTPUT; 156 | attributes.width = allocation.width; 157 | attributes.height = allocation.height; 158 | attributes.x = allocation.x; 159 | attributes.y = allocation.y; 160 | attributes_mask = Gdk.WindowAttributesType.X | Gdk.WindowAttributesType.Y; 161 | attributes.event_mask = overlay_widget.get_events () | Gdk.EventMask.EXPOSURE_MASK; 162 | 163 | var window = new Gdk.Window (this.get_window (), 164 | attributes, attributes_mask); 165 | 166 | //dialog_vbox.set_window (vtw.get_window()); 167 | overlay_widget.set_parent_window (window); 168 | overlay_widget.set_has_window (true); 169 | //vtw.overlay_notebook.show_all(); 170 | } 171 | 172 | }//MyOverlayBox 173 | -------------------------------------------------------------------------------- /altyo_quick_connectios.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | 19 | /* 20 | * http://developer.gnome.org/glib/2.30/glib-Simple-XML-Subset-Parser.html 21 | * http://gitorious.org/tuntun/tuntun/blobs/master/src/tuntun-auth-dialog.vala 22 | * 23 | * */ 24 | using Gtk; 25 | 26 | //const string GETTEXT_PACKAGE = "altyo"; 27 | 28 | enum QCOLUMN { 29 | NAME, 30 | HOST_NAME, 31 | USER_NAME, 32 | USER_PASSWORD, 33 | COMMAND, 34 | DESCRIPTION, 35 | CREATION_TIME, 36 | MODIFICATION_TIME, 37 | EXPIRATION_TIME 38 | } 39 | public class QConnect { 40 | public string name; 41 | public string? description; 42 | public int64 creation_time; 43 | public int64 modification_time; 44 | public int64 expiration_time; 45 | public string? user_name; 46 | public string? user_password; 47 | public string? host_name; 48 | public string? command; 49 | 50 | private int64 parse_time(string time_s){ 51 | if(time_s.length>0){ 52 | if(time_s.contains("(") && time_s.contains(")")){ 53 | var s = time_s.substring(time_s.index_of_char('(',0)+1,time_s.index_of_char(')',1)-1); 54 | return int.parse(s); 55 | } 56 | } 57 | return 0; 58 | } 59 | 60 | public QConnect(string[] data_list){ 61 | this.name=data_list[QCOLUMN.NAME]; 62 | this.description=data_list[QCOLUMN.DESCRIPTION]; 63 | this.creation_time=this.parse_time(data_list[QCOLUMN.CREATION_TIME]); 64 | this.modification_time=this.parse_time(data_list[QCOLUMN.MODIFICATION_TIME]); 65 | this.expiration_time=this.parse_time(data_list[QCOLUMN.EXPIRATION_TIME]); 66 | this.user_name=data_list[QCOLUMN.USER_NAME]; 67 | this.user_password=data_list[QCOLUMN.USER_PASSWORD]; 68 | this.host_name=data_list[QCOLUMN.HOST_NAME]; 69 | this.command=data_list[QCOLUMN.COMMAND]; 70 | //debug("name=%s description=%s creation_time=%d modification_time=%d expiration_time=%d user_name=%s user_password=%s host_name=%s command=%s", 71 | //this.name,this.description,(int)this.creation_time,(int)this.modification_time,(int)this.expiration_time,this.user_name,this.user_password,this.host_name,this.command); 72 | } 73 | }//class QConnect 74 | 75 | public class QConnections { 76 | private MySettings conf; 77 | public List children; 78 | 79 | //constructor 80 | public QConnections(MySettings conf) { 81 | this.conf = conf; 82 | this.children = new List (); 83 | foreach(string conn in this.conf.get_qconnection_list()){ 84 | debug("get_qconnection_list=%s",conn); 85 | string[] data = this.conf.get_qconnection_data_list(conn); 86 | debug("data=%d",data.length); 87 | if(data.length<8){ 88 | var t_l=data.length; 89 | for(var i=0;i<(8-t_l);i++) 90 | data+="";//add empty entries 91 | } 92 | 93 | if(data.length==8){ 94 | //add key name in to array[0] 95 | data +=data[data.length-1]; 96 | for(var i=data.length-2;i>0;i--){ 97 | data[i]=data[i-1]; 98 | } 99 | data[0]=conn;//key name 100 | var item = new QConnect(data); 101 | children.append(item); 102 | } 103 | } 104 | } 105 | }//class QConnections 106 | 107 | 108 | public class QList: HBox { 109 | private TreeView view; 110 | private QConnections qconn; 111 | private MySettings conf; 112 | private Gtk.Menu popup_menu; 113 | 114 | private Gtk.ActionGroup action_group; 115 | private TreeStore store; 116 | public VTMainWindow win_parent {get;set;default=null;} 117 | 118 | public QList(MySettings conf){ 119 | this.conf = conf; 120 | 121 | 122 | this.view = new TreeView (); 123 | var scroll = new ScrolledWindow (null, null); 124 | scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); 125 | scroll.add (this.view); 126 | this.pack_start(scroll,true,true,0); 127 | 128 | this.store = new TreeStore (9, typeof (string), typeof (string) 129 | , typeof (string), typeof (string), typeof (string), typeof (string) 130 | , typeof (string), typeof (string), typeof (string) ); 131 | this.view.set_model (store); 132 | 133 | CellRendererText crt; 134 | TreeViewColumn column; 135 | crt=new CellRendererText(); 136 | crt.edited.connect((path,new_text)=>{ 137 | debug("path=%s new_text=%s",path,new_text); 138 | TreeIter? iter=null; 139 | this.store.get_iter_from_string(out iter,path); 140 | if(!this.store.iter_has_child(iter)) 141 | store.set (iter, QCOLUMN.NAME, new_text,-1); 142 | }); 143 | column=new TreeViewColumn.with_attributes("Name",crt , "text", QCOLUMN.NAME, null); 144 | column.set_sort_indicator(true); 145 | this.view.insert_column (column,-1); 146 | crt=new CellRendererText(); 147 | crt.edited.connect((path,new_text)=>{ 148 | debug("path=%s new_text=%s",path,new_text); 149 | TreeIter? iter=null; 150 | this.store.get_iter_from_string(out iter,path); 151 | if(!this.store.iter_has_child(iter)) 152 | store.set (iter, QCOLUMN.HOST_NAME, new_text,-1); 153 | }); 154 | column=new TreeViewColumn.with_attributes( "host_name", crt, "text", QCOLUMN.HOST_NAME, null); 155 | this.view.insert_column (column,-1); 156 | crt=new CellRendererText(); 157 | crt.edited.connect((path,new_text)=>{ 158 | debug("path=%s new_text=%s",path,new_text); 159 | TreeIter? iter=null; 160 | this.store.get_iter_from_string(out iter,path); 161 | if(!this.store.iter_has_child(iter)) 162 | store.set (iter, QCOLUMN.USER_NAME, new_text,-1); 163 | }); 164 | column=new TreeViewColumn.with_attributes( "user_name", crt, "text", QCOLUMN.USER_NAME, null); 165 | this.view.insert_column (column,-1); 166 | crt=new CellRendererText(); 167 | crt.edited.connect((path,new_text)=>{ 168 | debug("path=%s new_text=%s",path,new_text); 169 | TreeIter? iter=null; 170 | this.store.get_iter_from_string(out iter,path); 171 | if(!this.store.iter_has_child(iter)) 172 | store.set (iter, QCOLUMN.USER_PASSWORD, new_text,-1); 173 | }); 174 | column=new TreeViewColumn.with_attributes( "user_password", crt, "text", QCOLUMN.USER_PASSWORD, null); 175 | this.view.insert_column (column,-1); 176 | crt=new CellRendererText(); 177 | crt.edited.connect((path,new_text)=>{ 178 | debug("path=%s new_text=%s",path,new_text); 179 | TreeIter? iter=null; 180 | this.store.get_iter_from_string(out iter,path); 181 | if(!this.store.iter_has_child(iter)) 182 | store.set (iter, QCOLUMN.COMMAND, new_text,-1); 183 | }); 184 | column=new TreeViewColumn.with_attributes( "command", crt, "text", QCOLUMN.COMMAND, null); 185 | this.view.insert_column (column,-1); 186 | crt=new CellRendererText(); 187 | crt.edited.connect((path,new_text)=>{ 188 | debug("path=%s new_text=%s",path,new_text); 189 | TreeIter? iter=null; 190 | this.store.get_iter_from_string(out iter,path); 191 | if(!this.store.iter_has_child(iter)) 192 | store.set (iter, QCOLUMN.DESCRIPTION, new_text,-1); 193 | }); 194 | crt.ellipsize_set=true; 195 | column=new TreeViewColumn.with_attributes( "Description", crt, "text", QCOLUMN.DESCRIPTION, null); 196 | this.view.insert_column (column,-1); 197 | this.view.insert_column_with_attributes (-1, "creation_time", new CellRendererText (), "text", QCOLUMN.CREATION_TIME, null); 198 | this.view.insert_column_with_attributes (-1, "modification_time", new CellRendererText (), "text", QCOLUMN.MODIFICATION_TIME, null); 199 | this.view.insert_column_with_attributes (-1, "expiration_time", new CellRendererText (), "text", QCOLUMN.EXPIRATION_TIME, null); 200 | 201 | this.qconn = new QConnections(this.conf); 202 | 203 | foreach(var conn in this.qconn.children){ 204 | debug("conn=%s",conn.name); 205 | var levels = conn.name.split("/"); 206 | debug("levels=%d",levels.length); 207 | TreeIter? level=null; 208 | TreeIter? sublevel=null; 209 | TreeIter? data_iter=null; 210 | TreePath path = new TreePath.first(); 211 | //TreeIter data_iter=store.get_iter_first(); 212 | for(var i=0;i{ 251 | debug("this.view.row_activated"); 252 | TreeIter? iter=null; 253 | store.get_iter(out iter,path); 254 | if(store.iter_has_child(iter)){ 255 | if(!this.view.is_row_expanded(path)) 256 | this.view.expand_row(path,false); 257 | else 258 | this.view.collapse_row(path); 259 | }else{ 260 | string command; 261 | string host_name; 262 | string user_name; 263 | string user_password; 264 | store.get(iter,QCOLUMN.COMMAND,out command,QCOLUMN.HOST_NAME, out host_name,QCOLUMN.USER_NAME,out user_name,QCOLUMN.USER_PASSWORD,out user_password,-1); 265 | debug("got command(%s)",command); 266 | if(command!=null && command!="" && GLib.Regex.match_simple("^ *xdg-open *",command,RegexCompileFlags.CASELESS,0)) 267 | Process.spawn_command_line_async(command);//run command 268 | else{ 269 | //unowned Gtk.Widget parent; 270 | //parent = this; 271 | //while(parent.parent!=null ){parent = parent.parent;} //find VTMainWindow 272 | //VTMainWindow vtw=(VTMainWindow)parent; 273 | //todo: prevent double ssh 274 | var tauth = new TildaAuth(user_name,user_password,host_name,command); 275 | ((VTTerminal)this.win_parent.active_tab.object).try_run_command(tauth); 276 | this.action_group.get_action("altyo_toogle_quick_list").activate(); 277 | } 278 | } 279 | } ); 280 | 281 | 282 | 283 | 284 | this.view.button_press_event.connect((event)=>{ 285 | //public void popup_menu(Gdk.EventButton event){ 286 | if(event.type==Gdk.EventType.BUTTON_PRESS){ 287 | if(event.button== 3){//right mouse button 288 | this.create_popup(); 289 | //menu.ref(); 290 | return true; 291 | } 292 | } 293 | debug("tut"); 294 | return false; 295 | //} 296 | }); 297 | 298 | this.view.key_press_event.connect(on_key_press_event); 299 | 300 | Gdk.RGBA c = new Gdk.RGBA(); 301 | c.parse("#000000");//black todo: make same color as vte 302 | c.alpha = 1.0;//transparency 303 | this.view.override_background_color(StateFlags.NORMAL, c); 304 | //this.parent.override_background_color(StateFlags.NORMAL, c); 305 | c.parse("#AAFF88");//black todo: make same color as vte 306 | c.alpha = 1.0;//transparency 307 | this.view.override_color(StateFlags.NORMAL, c); 308 | 309 | this.can_focus=false; 310 | this.can_default = false; 311 | this.has_focus = false; 312 | //this.setup_keyboard_accelerators(); 313 | 314 | this.view.map.connect(()=>{ 315 | this.action_group.sensitive=true; 316 | view.grab_focus(); 317 | //this.view.get_window().set_events(Gdk.EventMask.SCROLL_MASK); 318 | }); 319 | 320 | this.view.set_search_equal_func(search_inline); 321 | //this.view.hover_expand=true; 322 | //this.view.model=true; 323 | 324 | /*var scrollbar = new VScrollbar(((Scrollable)this.view).get_vadjustment()); 325 | scrollbar.show () ; 326 | this.pack_end(scrollbar,false,false,0);*/ 327 | 328 | this.show_all(); 329 | } 330 | 331 | 332 | private void add_window_accel(string name,string? label, string? tooltip, string? stock_id,string default_accel, MyCallBack cb){ 333 | this.add_window_accel_real(new Gtk.Action(name, label, tooltip, stock_id),conf.get_accel_string(name,default_accel),cb); 334 | } 335 | 336 | private void add_window_toggle_accel(string name,string? label, string? tooltip, string? stock_id,string default_accel, MyCallBack cb){ 337 | this.add_window_accel_real(new Gtk.ToggleAction(name, label, tooltip, stock_id),conf.get_accel_string(name,default_accel),cb); 338 | } 339 | 340 | private void add_window_accel_real(Gtk.Action action, string accel, MyCallBack cb){ 341 | 342 | //we can't connect cb dirrectly to action.activate 343 | //so, using lambda again =( 344 | action.activate.connect(()=>{cb(action);}); 345 | //add in to action_group to make a single repository 346 | this.action_group.add_action_with_accel (action,accel); 347 | action.set_accel_group (this.win_parent.accel_group);//use main window accel group 348 | action.connect_accelerator (); 349 | //inc refcount otherwise action will be freed at the end of this function 350 | action.ref(); 351 | } 352 | 353 | private void set_active_column(QCOLUMN new_index){ 354 | TreePath path; 355 | TreeViewColumn s_column; 356 | this.view.get_cursor(out path,out s_column); 357 | 358 | List tvc=this.view.get_columns (); 359 | 360 | unowned TreeViewColumn my_column=null; 361 | foreach(var column in tvc){ 362 | var index=tvc.index(column);//know better way? 363 | if (index==new_index ){ 364 | my_column=column; 365 | }else 366 | column.set_sort_indicator(false); 367 | } 368 | //~ if(!my_column.get_sort_indicator()) 369 | my_column.set_sort_indicator(true); 370 | //~ else{ 371 | //~ if(SortType.ASCENDING == my_column.get_sort_order()) 372 | //~ my_column.set_sort_order(SortType.DESCENDING); 373 | //~ else 374 | //~ my_column.set_sort_order(SortType.ASCENDING); 375 | //~ } 376 | 377 | this.view.set_cursor_on_cell(path,my_column,null,((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active); 378 | this.view.set_search_column(new_index); 379 | 380 | } 381 | 382 | public void setup_keyboard_accelerators() { 383 | debug("setup_keyboard_accelerators"); 384 | 385 | //this.accel_group = new Gtk.AccelGroup(); 386 | //((Window)this.win_parent).add_accel_group (accel_group); 387 | 388 | this.action_group = new Gtk.ActionGroup("QList"); 389 | this.action_group.sensitive=false; 390 | 391 | this.add_window_accel("altyo_toogle_quick_list", "Show/Hide Quick list", "Show/Hide Quick list", Gtk.Stock.QUIT,"D",()=> { 392 | debug("QuickLIst d"); 393 | this.action_group.sensitive=false; 394 | this.win_parent.action_group.sensitive=true; 395 | this.win_parent.action_group.get_action("altyo_toogle_quick_list").activate(); 396 | }); 397 | 398 | this.add_window_toggle_accel("qlist_edit_table", "Edit table", "Edit table", Gtk.Stock.EDIT,"E",()=> { 399 | /*var selection = this.view.get_selection(); 400 | TreeModel model; 401 | TreeIter iter; 402 | if(selection.get_selected(out model,out iter)){ 403 | store.get_path(iter); 404 | 405 | }*/ 406 | List tvc=this.view.get_columns (); 407 | //tvc=unowned tvc.next;//skip name 408 | foreach(var column in tvc){ 409 | List cells = column.get_cells(); 410 | var index=tvc.index(column);//know better way? 411 | if( index==QCOLUMN.DESCRIPTION || 412 | index==QCOLUMN.USER_NAME || 413 | index==QCOLUMN.USER_PASSWORD || 414 | index==QCOLUMN.HOST_NAME || 415 | index==QCOLUMN.COMMAND || 416 | index==QCOLUMN.NAME ) 417 | foreach(var renderer in cells){ 418 | ((CellRendererText)renderer).editable=((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active; 419 | } 420 | } 421 | }); 422 | 423 | this.add_window_accel("qlist_create_folder", "Create Folder", "Create Folder", Gtk.Stock.DIRECTORY,"D",()=> { 424 | if(((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active){ 425 | var selection = this.view.get_selection(); 426 | TreeModel model; 427 | TreeIter iter; 428 | TreeIter samelevel; 429 | if(selection.get_selected(out model,out iter)){ 430 | //TreePath path = store.get_path(iter); 431 | //path.up(); 432 | this.store.insert_after (out samelevel, null, iter); 433 | debug("sublevel.get_path=%s",this.store.get_path(samelevel).to_string()); 434 | this.store.set (samelevel, 0,"", -1); 435 | 436 | } 437 | } 438 | }); 439 | 440 | this.add_window_accel("qlist_create_sub_folder", "Create Sub Folder", "Create Sub Folder", Gtk.Stock.DIRECTORY,"D",()=> { 441 | if(((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active){ 442 | var selection = this.view.get_selection(); 443 | TreeModel model; 444 | TreeIter iter; 445 | TreeIter samelevel; 446 | if(selection.get_selected(out model,out iter)){ 447 | //TreePath path = store.get_path(iter); 448 | //path.up(); 449 | this.store.append(out samelevel, iter); 450 | debug("sublevel.get_path=%s",this.store.get_path(samelevel).to_string()); 451 | this.store.set (samelevel, 0,"", -1); 452 | 453 | } 454 | } 455 | }); 456 | 457 | this.add_window_accel("qlist_new_item", "Create new item", "Create new item", Gtk.Stock.NEW,"N",()=> { 458 | overlay_dialog(); 459 | return; 460 | if(((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active){ 461 | var selection = this.view.get_selection(); 462 | TreeModel model; 463 | TreeIter iter; 464 | TreeIter samelevel; 465 | TreeIter? tmp_iter; 466 | if(selection.get_selected(out model,out iter)){ 467 | this.store.insert_after (out samelevel, null, iter); 468 | TreePath path = store.get_path(samelevel); 469 | string qpath=""; 470 | debug("while(path.up())"); 471 | while(path.up() && path.get_depth()>0){ 472 | string name; 473 | this.store.get_iter(out tmp_iter,path); 474 | this.store.get (tmp_iter,QCOLUMN.NAME, out name,-1); 475 | if(name!=null) 476 | qpath=name+"/"+qpath; 477 | } 478 | 479 | debug("sublevel.get_path=%s",store.get_path(samelevel).to_string()); 480 | var conn = new QConnect({qpath,"","","","","Проверка \n комментария","(%d)%s".printf(((int)new DateTime.now_local()),new DateTime.now_local().format ("%x %X")),"",""}); 481 | this.qconn.children.append(conn); 482 | this.store.set (samelevel, 483 | QCOLUMN.NAME, /*""*/conn.name, 484 | QCOLUMN.DESCRIPTION, conn.description, 485 | QCOLUMN.CREATION_TIME,(conn.creation_time!=0?new DateTime.now_local().format ("%x %X"):""), 486 | QCOLUMN.MODIFICATION_TIME,(conn.modification_time!=0?new DateTime.now_local().format ("%x %X"):""), 487 | QCOLUMN.EXPIRATION_TIME,(conn.expiration_time!=0?new DateTime.from_unix_local (conn.expiration_time).format ("%x %X"):""), 488 | QCOLUMN.USER_NAME, conn.user_name, 489 | QCOLUMN.USER_PASSWORD, conn.user_password, 490 | QCOLUMN.HOST_NAME, conn.host_name, 491 | QCOLUMN.COMMAND, conn.command, 492 | -1); 493 | 494 | } 495 | } 496 | }); 497 | 498 | this.add_window_accel("qlist_edit_name", "Edit Name", "Edit Name", null,"1",()=> { 499 | this.set_active_column(QCOLUMN.NAME); 500 | }); 501 | 502 | this.add_window_accel("qlist_edit_host_name", "Edit Host Name", "Edit Host Name", null,"2",()=> { 503 | this.set_active_column(QCOLUMN.HOST_NAME); 504 | }); 505 | 506 | this.add_window_accel("qlist_edit_user_name", "Edit User Name", "Edit User Name", null,"3",()=> { 507 | this.set_active_column(QCOLUMN.USER_NAME); 508 | }); 509 | 510 | this.add_window_accel("qlist_edit_password", "Edit Password", "Edit Password", null,"4",()=> { 511 | this.set_active_column(QCOLUMN.USER_PASSWORD); 512 | }); 513 | 514 | this.add_window_accel("qlist_edit_command", "Edit command", "Edit command", null,"5",()=> { 515 | this.set_active_column(QCOLUMN.COMMAND); 516 | }); 517 | 518 | this.add_window_accel("qlist_edit_description", "Edit description", "Edit description", null,"6",()=> { 519 | this.set_active_column(QCOLUMN.DESCRIPTION); 520 | }); 521 | 522 | this.add_window_accel("qlist_delete_row", "Delete row", "Delete row", Gtk.Stock.DELETE,"Delete",()=> { 523 | if(((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active){ 524 | TreePath path; 525 | TreeViewColumn s_column; 526 | TreeIter? iter=null; 527 | this.view.get_cursor(out path,out s_column); 528 | if(store.get_iter(out iter,path)) 529 | if(!store.iter_has_child(iter)){ 530 | this.store.remove(ref iter); 531 | if(store.get_iter(out iter,path)) 532 | this.view.set_cursor(path,null,false); 533 | else if(path.prev()) 534 | this.view.set_cursor(path,null,false); 535 | else if(path.up()) 536 | this.view.set_cursor(path,null,false); 537 | } 538 | } 539 | }); 540 | 541 | this.create_popup(); 542 | }//setup_keyboard_accelerators 543 | 544 | public void create_popup(){ 545 | this.action_group.get_action("qlist_create_folder").sensitive=((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active; 546 | this.action_group.get_action("qlist_create_sub_folder").sensitive=((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active; 547 | this.action_group.get_action("qlist_new_item").sensitive=((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active; 548 | this.action_group.get_action("qlist_delete_row").sensitive=((Gtk.ToggleAction)this.action_group.get_action("qlist_edit_table")).active; 549 | 550 | if(this.popup_menu==null){ 551 | this.popup_menu = new Gtk.Menu(); 552 | Gtk.MenuItem menuitem; 553 | 554 | menuitem = (Gtk.MenuItem)this.action_group.get_action("qlist_edit_table").create_menu_item(); 555 | this.popup_menu.append(menuitem); 556 | 557 | menuitem = new Gtk.SeparatorMenuItem(); 558 | this.popup_menu.append(menuitem); 559 | 560 | menuitem = (Gtk.MenuItem)this.action_group.get_action("qlist_create_folder").create_menu_item(); 561 | this.popup_menu.append(menuitem); 562 | 563 | menuitem = (Gtk.MenuItem)this.action_group.get_action("qlist_create_sub_folder").create_menu_item(); 564 | this.popup_menu.append(menuitem); 565 | 566 | menuitem = (Gtk.MenuItem)this.action_group.get_action("qlist_new_item").create_menu_item(); 567 | this.popup_menu.append(menuitem); 568 | 569 | menuitem = new Gtk.SeparatorMenuItem(); 570 | this.popup_menu.append(menuitem); 571 | 572 | menuitem = (Gtk.MenuItem)this.action_group.get_action("qlist_delete_row").create_menu_item(); 573 | this.popup_menu.append(menuitem); 574 | 575 | this.popup_menu.show_all(); 576 | }else{ 577 | this.popup_menu.popup(null, null, null, 3, 0); 578 | } 579 | } 580 | 581 | bool search_inline (Gtk.TreeModel model, int column, string key, 582 | Gtk.TreeIter iter) { 583 | var path = store.get_path(iter); 584 | if(store.iter_has_child(iter)){ 585 | if(!this.view.is_row_expanded(path)) 586 | this.view.expand_row(path,false); 587 | }else{ 588 | string? message=null; 589 | this.store.get (iter, column, out message); 590 | debug("search_inline message=%s",message); 591 | if(message!=null) 592 | return !GLib.Regex.match_simple(".*"+key+".*",message,RegexCompileFlags.CASELESS,0); 593 | //RegexCompileFlags.CASELESS - ignore case 594 | } 595 | return true; 596 | } 597 | 598 | bool on_key_press_event (Gdk.EventKey event){ 599 | //var keyname = Gdk.keyval_name(event.keyval); 600 | event.state &= Gtk.accelerator_get_default_mod_mask(); 601 | if( event.keyval==0xff0d && /*GDK_KEY_Return*/ 602 | ((event.state & Gdk.ModifierType.CONTROL_MASK)>0) 603 | ){ 604 | debug("this.view.row_activated"); 605 | 606 | TreePath path; 607 | TreeViewColumn s_column; 608 | TreeIter? iter=null; 609 | this.view.get_cursor(out path,out s_column); 610 | 611 | store.get_iter(out iter,path); 612 | if(!store.iter_has_child(iter)){ 613 | string command; 614 | string host_name; 615 | string user_name; 616 | string user_password; 617 | store.get(iter,QCOLUMN.HOST_NAME, out host_name,QCOLUMN.USER_NAME,out user_name,QCOLUMN.USER_PASSWORD,out user_password,-1); 618 | 619 | command="ssh,paste-password"; 620 | debug("try_run_command host_name=%s,user_name=%s,user_password=%s,command=%s",host_name,user_name,user_password,command); 621 | var tauth = new TildaAuth(user_name,user_password,host_name,command); 622 | ((VTTerminal)this.win_parent.active_tab.object).try_run_command(tauth); 623 | this.action_group.get_action("altyo_toogle_quick_list").activate(); 624 | 625 | } 626 | 627 | } 628 | return false; 629 | } 630 | 631 | /*public override void get_preferred_width (out int o_minimum_width, out int o_natural_width) { 632 | o_minimum_width=o_natural_width= this.win_parent.terminal_width; 633 | } 634 | 635 | public override void get_preferred_height_for_width (int width,out int minimum_height, out int natural_height) { 636 | minimum_height=natural_height= this.win_parent.terminal_height; 637 | } 638 | 639 | public override SizeRequestMode get_request_mode () { 640 | return (Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH); 641 | }*/ 642 | 643 | public void overlay_dialog(){ 644 | debug("overlay_dialog"); 645 | 646 | //this.pack_start(scroll,true,true,0); 647 | 648 | VTMainWindow vtw=(VTMainWindow)this.get_toplevel(); 649 | 650 | var dialog_vbox = new VBox(false, 0); 651 | //~ dialog_vbox.set_has_window (true); 652 | var but = new Button.with_label("test"); 653 | 654 | dialog_vbox.add(but); 655 | 656 | vtw.overlay_notebook.prepend_page (dialog_vbox,null); 657 | vtw.overlay_notebook.show_all(); 658 | vtw.overlay_notebook.show(); 659 | 660 | /*var attributes = new Gdk.WindowAttr(); 661 | int attributes_mask; 662 | Gtk.Allocation allocation; 663 | 664 | dialog_vbox.get_allocation (out allocation); 665 | 666 | attributes.window_type = Gdk.WindowType.CHILD; 667 | attributes.wclass = Gdk.WindowWindowClass.OUTPUT; 668 | attributes.width = allocation.width; 669 | attributes.height = allocation.height; 670 | attributes.x = allocation.x; 671 | attributes.y = allocation.y; 672 | attributes_mask = Gdk.WindowAttributesType.X | Gdk.WindowAttributesType.Y; 673 | attributes.event_mask = vtw.get_events () | Gdk.EventMask.EXPOSURE_MASK; 674 | 675 | var window = new Gdk.Window (vtw.get_window (), 676 | attributes, attributes_mask); 677 | 678 | //dialog_vbox.set_window (vtw.get_window()); 679 | vtw.overlay_notebook.set_window (window); 680 | vtw.overlay_notebook.show_all();*/ 681 | 682 | 683 | //this.overlay_notebook.set_show_tabs(false); 684 | }//overlay_dialog 685 | 686 | }//class QList 687 | -------------------------------------------------------------------------------- /data/altyo.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=AltYo 3 | TryExec=altyo 4 | Exec=altyo 5 | Icon=altyo 6 | Terminal=false 7 | Type=Application 8 | Categories=GTK;Utility;TerminalEmulator; 9 | StartupNotify=true 10 | Keywords=Run; 11 | Actions=New 12 | -------------------------------------------------------------------------------- /data/altyo.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | altyo.svg 6 | preferences.glade 7 | encodings_list.glade 8 | main_window_encodings_combo.glade 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/altyo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linvinus/AltYo/6dd200e38c7038c159f1f96986ef9bbbb3794a3f/data/altyo.png -------------------------------------------------------------------------------- /data/altyo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 42 | 44 | 46 | 50 | 54 | 55 | 57 | 61 | 65 | 66 | 68 | 72 | 76 | 77 | 85 | 89 | 93 | 94 | 96 | 100 | 104 | 105 | 108 | 111 | 112 | 120 | 128 | 138 | 147 | 149 | 153 | 157 | 158 | 168 | 170 | 174 | 178 | 179 | 181 | 190 | 191 | 198 | 201 | 202 | 210 | 218 | 222 | 226 | 227 | 236 | 245 | 254 | 263 | 272 | 283 | 292 | 301 | 311 | 322 | 331 | 332 | 334 | 335 | 337 | image/svg+xml 338 | 340 | 341 | 342 | 343 | 344 | 357 | 360 | 365 | 370 | 375 | 385 | 395 | 396 | 405 | 410 | 415 | 420 | 425 | 430 | 435 | 442 | 447 | 452 | 457 | 462 | 472 | 473 | 474 | -------------------------------------------------------------------------------- /data/altyo_standalone.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=AltYo Stand-alone 3 | Exec=altyo --standalone 4 | Icon=altyo 5 | Terminal=false 6 | Type=Application 7 | Categories=GTK;Utility;TerminalEmulator; 8 | -------------------------------------------------------------------------------- /data/encodings_list.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ISO-8859-1 14 | Western 15 | 16 | 17 | ISO-8859-2 18 | Central European 19 | 20 | 21 | ISO-8859-3 22 | South European 23 | 24 | 25 | ISO-8859-4 26 | Baltic 27 | 28 | 29 | ISO-8859-5 30 | Cyrillic 31 | 32 | 33 | ISO-8859-6 34 | Arabic 35 | 36 | 37 | ISO-8859-7 38 | Greek 39 | 40 | 41 | ISO-8859-8 42 | Hebrew Visual 43 | 44 | 45 | ISO-8859-8-I 46 | Hebrew 47 | 48 | 49 | ISO-8859-9 50 | Turkish 51 | 52 | 53 | ISO-8859-10 54 | Nordic 55 | 56 | 57 | ISO-8859-13 58 | Baltic 59 | 60 | 61 | ISO-8859-14 62 | Celtic 63 | 64 | 65 | ISO-8859-15 66 | Western 67 | 68 | 69 | ISO-8859-16 70 | Romanian 71 | 72 | 73 | UTF-8 74 | Unicode 75 | 76 | 77 | ARMSCII-8 78 | Armenian 79 | 80 | 81 | BIG5 82 | Chinese Traditional 83 | 84 | 85 | BIG5-HKSCS 86 | Chinese Traditional 87 | 88 | 89 | CP866 90 | Cyrillic/Russian 91 | 92 | 93 | EUC-JP 94 | Japanese 95 | 96 | 97 | EUC-KR 98 | Korean 99 | 100 | 101 | EUC-TW 102 | Chinese Traditional 103 | 104 | 105 | GB18030 106 | Chinese Simplified 107 | 108 | 109 | GB2312 110 | Chinese Simplified 111 | 112 | 113 | GBK 114 | Chinese Simplified 115 | 116 | 117 | GEORGIAN-PS 118 | Georgian 119 | 120 | 121 | IBM850 122 | Western 123 | 124 | 125 | IBM852 126 | Central European 127 | 128 | 129 | IBM855 130 | Cyrillic 131 | 132 | 133 | IBM857 134 | Turkish 135 | 136 | 137 | IBM862 138 | Hebrew 139 | 140 | 141 | IBM864 142 | Arabic 143 | 144 | 145 | ISO-2022-JP 146 | Japanese 147 | 148 | 149 | ISO-2022-KR 150 | Korean 151 | 152 | 153 | ISO-IR-111 154 | Cyrillic 155 | 156 | 157 | KOI8-R 158 | Cyrillic 159 | 160 | 161 | KOI8-U 162 | Cyrillic/Ukrainian 163 | 164 | 165 | MAC_ARABIC 166 | Arabic 167 | 168 | 169 | MAC_CE 170 | Central European 171 | 172 | 173 | MAC_CROATIAN 174 | Croatian 175 | 176 | 177 | MAC-CYRILLIC 178 | Cyrillic 179 | 180 | 181 | MAC_DEVANAGARI 182 | Hindi 183 | 184 | 185 | MAC_FARSI 186 | Persian 187 | 188 | 189 | MAC_GREEK 190 | Greek 191 | 192 | 193 | MAC_GUJARATI 194 | Gujarati 195 | 196 | 197 | MAC_GURMUKHI 198 | Gurmukhi 199 | 200 | 201 | MAC_HEBREW 202 | Hebrew 203 | 204 | 205 | MAC_ICELANDIC 206 | Icelandic 207 | 208 | 209 | MAC_ROMAN 210 | Western 211 | 212 | 213 | MAC_ROMANIAN 214 | Romanian 215 | 216 | 217 | MAC_TURKISH 218 | Turkish 219 | 220 | 221 | MAC_UKRAINIAN 222 | Cyrillic/Ukrainian 223 | 224 | 225 | SHIFT_JIS 226 | Japanese 227 | 228 | 229 | TCVN 230 | Vietnamese 231 | 232 | 233 | TIS-620 234 | Thai 235 | 236 | 237 | UHC 238 | Korean 239 | 240 | 241 | VISCII 242 | Vietnamese 243 | 244 | 245 | WINDOWS-1250 246 | Central European 247 | 248 | 249 | WINDOWS-1251 250 | Cyrillic 251 | 252 | 253 | WINDOWS-1252 254 | Western 255 | 256 | 257 | WINDOWS-1253 258 | Greek 259 | 260 | 261 | WINDOWS-1254 262 | Turkish 263 | 264 | 265 | WINDOWS-1255 266 | Hebrew 267 | 268 | 269 | WINDOWS-1256 270 | Arabic 271 | 272 | 273 | WINDOWS-1257 274 | Baltic 275 | 276 | 277 | WINDOWS-1258 278 | Vietnamese 279 | 280 | 281 | UTF-7 282 | Unicode 283 | 284 | 285 | UTF-16 286 | Unicode 287 | 288 | 289 | UCS-2 290 | Unicode 291 | 292 | 293 | UCS-4 294 | Unicode 295 | 296 | 297 | JOHAB 298 | Korean 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | Auto 310 | 311 | 312 | ASCII Backspace 313 | 314 | 315 | ASCII Delete 316 | 317 | 318 | Delete sequence 319 | 320 | 321 | TTY "erase" 322 | 323 | 324 | 325 | 326 | -------------------------------------------------------------------------------- /data/main_window_encodings_combo.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | True 7 | True 8 | True 9 | 0 10 | False 11 | 1 12 | 13 | 14 | 15 | 1 16 | 17 | 18 | 19 | 20 | True 21 | True 22 | 23 | 24 | 25 | 26 | True 27 | False 28 | True 29 | Backspace key binding 30 | False 31 | 32 | 33 | 34 | 35 | end 36 | 37 | 38 | 0 39 | 40 | 41 | 42 | 43 | True 44 | False 45 | True 46 | Delete key binding 47 | False 48 | 0 49 | 50 | 51 | 52 | 53 | end 54 | 55 | 56 | 0 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /hvbox.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 3 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | */ 17 | 18 | 19 | using Gtk; 20 | using Cairo; 21 | 22 | private class HVBoxItem : Object{ 23 | public unowned Widget widget; 24 | public int max_width = -1; 25 | public bool ignore = false; 26 | public ulong drag_begin_id = 0; 27 | public ulong drag_data_get_id = 0; 28 | public ulong drag_end_id = 0; 29 | public HVBoxItem(Widget W){ 30 | this.widget = W; 31 | } 32 | ~HVBoxItem(){ 33 | debug("~HVBoxItem"); 34 | } 35 | // public void destroy(){ 36 | //~ base.destroy(); 37 | // delete (void*) this; 38 | // } 39 | } 40 | 41 | public class HVBox : Container { 42 | 43 | private int height = 28; 44 | private int cur_level = 0; 45 | 46 | private Gtk.SizeRequestMode mode = Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH; 47 | 48 | private GLib.List children;//child will be destroyed as soon as it will be removed from List 49 | //private Window HVBParent; 50 | 51 | private bool drop_data_ready { get; set; default = false; } 52 | private bool drop_occured { get; set; default = false; } 53 | private TargetList drop_targets { get; set; default = null; } 54 | private string[]? drop_uris { get; set; default = null; } 55 | private Window dnd_window { get; set; default = null; } 56 | private bool dnd_inprocess { get; set; default = false; } 57 | 58 | public bool background_only_behind_widgets { get; set; default = true; } 59 | public bool minimize_size { get; set; default = true; } 60 | public signal void child_reordered(Widget child, uint new_index); 61 | public signal void on_dnd_above_changed(Widget dnd_widget,Widget above); 62 | private int last_dnd_x = 0; 63 | private int last_dnd_y = 0; 64 | private unowned HVBoxItem last_dnd_above_item = null; 65 | private unowned HVBoxItem last_dnd_item = null; 66 | //~ public static enum DragInfo { 67 | //~ TEXT_URI_LIST 68 | //~ } 69 | 70 | const TargetEntry[] target_entries = { 71 | { "GTK_HVBOX_ITEM", (1 << 0) , 0 } 72 | }; 73 | 74 | 75 | public HVBox(/*Window parent*/) { 76 | set_has_window (false); 77 | children = new List (); 78 | //HVBParent=parent; 79 | 80 | /* create list of supported drop targets */ 81 | //~ TargetEntry[] target_entries = { 82 | //~ {"text/uri-list", 0, DragInfo.TEXT_URI_LIST } 83 | //~ }; 84 | 85 | 86 | /* remember this list for use in DnD handlers */ 87 | drop_targets = new TargetList (target_entries); 88 | 89 | /* set the view as a drag destination for these targets */ 90 | drag_dest_set (this, 0, target_entries, Gdk.DragAction.MOVE); 91 | //this.set_reallocate_redraws(true);//redraw all elements, needed for redraw HVBox border 92 | //this.resize_mode=ResizeMode.QUEUE; //this break window size 93 | name="HVBox"; 94 | } 95 | 96 | public override bool drag_motion (Gdk.DragContext context, 97 | //public bool some_drag_motion (Gdk.DragContext context, 98 | int x, 99 | int y, 100 | uint time) { 101 | //debug("drag_motion drop_data_ready=%s\n",drop_data_ready.to_string()); 102 | this.last_dnd_x=x; 103 | this.last_dnd_y=y; 104 | 105 | /* request drop data on demand */ 106 | if (!drop_data_ready) { 107 | /* check if we can handle the drag data (only text/uri-list supported) */ 108 | var target = drag_dest_find_target (this, context, drop_targets); 109 | debug("drag_motion drag_dest_find_target\n"); 110 | if (target == Gdk.Atom.intern_static_string ("GTK_HVBOX_ITEM")) { 111 | /* request drop data from the source */ 112 | drag_get_data (this, context, target, time); 113 | } 114 | 115 | /* we are not ready to drop yet */ 116 | Gdk.drag_status (context, 0, time); 117 | } else { 118 | /* create a file object for the URI */ 119 | //var file = GLib.File.new_for_uri (drop_uris[0]); 120 | //~ debug("drag_motion uri=%s\n",drop_uris[0]); 121 | 122 | /* find the correct category for it */ 123 | //~ CategoryExpander? expander = null; 124 | //~ if (find_category_for_file (file, out expander)) { 125 | //~ if (expander.drop_indicator != null) { 126 | //~ expander.drop_indicator.is_drop_target = true; 127 | //~ expander.drop_indicator.set_visible (true); 128 | //~ } 129 | 130 | /* we have drop data, now we can create the bookmark */ 131 | Gdk.drag_status (context, Gdk.DragAction.MOVE, time); 132 | //~ } else { 133 | /* we have an unsupported drop URI, cannot handle it */ 134 | //~ Gdk.drag_status (context, 0, time); 135 | //~ } 136 | } 137 | 138 | return true;//we a ready 139 | } 140 | 141 | public override void drag_leave (Gdk.DragContext context, uint time) { 142 | debug ("drag leave, reset flags\n"); 143 | } 144 | 145 | public override bool drag_drop (Gdk.DragContext context, 146 | int x, 147 | int y, 148 | uint time) 149 | { 150 | debug ("drag_drop\n"); 151 | 152 | /* determine the DnD target and see if we can handle it */ 153 | var target = drag_dest_find_target (this, context, drop_targets); 154 | if (target == Gdk.Atom.intern_static_string ("GTK_HVBOX_ITEM")) { 155 | debug ("drag drop, supports target, perform drop"); 156 | 157 | /* set flag so that drag_data_received knows we are dropping for real */ 158 | drop_occured = true; 159 | 160 | /* request data from drag source */ 161 | drag_get_data (this, context, target, time); 162 | 163 | /* we will call drag_finish later */ 164 | return true; 165 | } else { 166 | debug ("drag drop, target unsupported, cancel drop"); 167 | 168 | /* cancel drop */ 169 | return false; 170 | } 171 | 172 | } 173 | 174 | 175 | public override void drag_data_received (Gdk.DragContext context, 176 | int x, 177 | int y, 178 | SelectionData selection_data, 179 | uint info, 180 | uint time) 181 | { 182 | debug ("drag data received x=%d y=%d",x,y); 183 | 184 | string[] uris = selection_data.get_uris (); 185 | 186 | 187 | if ( !drop_data_ready && selection_data.get_target () == Gdk.Atom.intern_static_string ("GTK_HVBOX_ITEM")) { 188 | drop_data_ready = true; 189 | 190 | if (uris != null) { 191 | debug ("request from drag motion, have uris"); 192 | } else { 193 | debug ("request from drag motion, don't have uris"); 194 | } 195 | } 196 | 197 | if (drop_occured) { 198 | /* reset the drop state */ 199 | drop_occured = false; 200 | ulong* data; 201 | data = (ulong[])selection_data.get_data(); 202 | //if(data==null)return; 203 | if(data!=null){ 204 | debug ("data data= %d",(int)((ulong)data[0])); 205 | 206 | unowned HVBoxItem** pitem=(HVBoxItem**)data[0]; 207 | if(pitem==null || !(*pitem is HVBoxItem) )return; 208 | unowned HVBoxItem dnd_item=*pitem; 209 | 210 | debug ("data = %d %s",(int)(pitem),dnd_item.widget.get_type().name()); 211 | 212 | 213 | /********************************/ 214 | var line_h = 0; 215 | var dnd_done = false; 216 | var allocation = Gtk.Allocation();//don't use new for struct 217 | var width = this.get_allocated_width(); 218 | unowned Gtk.StyleContext style_context = this.get_style_context(); 219 | Gtk.Border border=style_context.get_border(StateFlags.NORMAL); 220 | 221 | allocation.x=0; 222 | allocation.y=0; 223 | allocation.height=0; 224 | allocation.width=0; 225 | 226 | unowned List item_it=null; 227 | unowned List end_of_line=null; 228 | for (item_it = this.children; !dnd_done && item_it != null; item_it = item_it.next) { 229 | 230 | end_of_line=item_it; 231 | line_h = get_line_height(ref end_of_line, width-border.left-border.right,false); 232 | if((allocation.y+line_h)>y){ 233 | allocation.x = 0 ;//start of the line 234 | allocation.height=line_h;//base height for line 235 | 236 | unowned List line_item=item_it; 237 | 238 | for (line_item=item_it; (line_item != null && end_of_line != null) && 239 | line_item != end_of_line.next ; line_item = line_item.next) { 240 | 241 | unowned HVBoxItem item = line_item.data; 242 | unowned Widget widget = item.widget; 243 | 244 | var ingnore_h = 0; 245 | allocation.width=widget.get_allocated_width(); 246 | 247 | debug("\torig2 size_allocate position=%d x=%d y=%d w=%d h=%d\n",this.children.position(line_item),allocation.x,allocation.y,allocation.width,allocation.height); 248 | 249 | if(line_item == end_of_line && x>allocation.x+allocation.width){ 250 | if(dnd_item==line_item.data){ //ignore same position 251 | dnd_done=true; 252 | break; 253 | } 254 | this.children.remove(dnd_item); 255 | var new_pos=this.children.position(line_item)+1; 256 | this.children.insert( dnd_item , new_pos); 257 | dnd_done=true; 258 | debug("Found at EOL! Xx=%d Yy=%d\n",x,y); 259 | break; 260 | } 261 | 262 | if(x allocation.y && y < (allocation.y+(allocation.height)) ) && 289 | //~ x < orig_pos_w ){ 290 | debug("Found at the end! Xx=%d Yy=%d\n",x,y); 291 | this.children.remove(dnd_item); 292 | //this.children.insert( item2 , this.children.position(item)); 293 | this.children.append(dnd_item); 294 | dnd_done=true; 295 | //~ } 296 | 297 | } 298 | 299 | 300 | //debug("orig2 size_allocate x=%d y=%d w=%d h=%d\n",allocation.x,allocation.y,allocation.width,allocation.height); 301 | 302 | //minimum_height=natural_height=allocation.height; 303 | 304 | /********************************/ 305 | }//if(!data==null) 306 | 307 | if (drop_uris != null) { 308 | debug ("have uris, create bookmark now"); 309 | } else { 310 | debug ("don't have uris, abort drag-and-drop"); 311 | } 312 | 313 | /* tell the drag source that we handled the drop */ 314 | drag_finish (context, drop_uris != null, false, time); 315 | 316 | /* disable highlighting and release the drag data */ 317 | drag_leave (context, time); 318 | } 319 | } 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | //~ public static Gdk.Rectangle get_primary_monitor_geometry () { 328 | //~ Gdk.Rectangle r = {0, 0}; 329 | //~ var screen = Gdk.Screen.get_default (); 330 | //~ screen.get_monitor_geometry (screen.get_primary_monitor(), out r); 331 | //~ return r; 332 | //~ } 333 | 334 | private int get_line_height (ref unowned List first_item=null,int width, bool get_max_natural_height = false) { 335 | 336 | if(first_item==null) 337 | return -1;//assert 338 | 339 | int minimum_height = 0; 340 | int natural_height = 0; 341 | int natural_width = 0; 342 | 343 | var allocation = Gtk.Allocation();//don't use new for struct 344 | 345 | allocation.x=0; 346 | allocation.y=0; 347 | allocation.height=0; 348 | allocation.width=0; 349 | 350 | var sum_w=0; 351 | 352 | 353 | unowned List item_it=null; 354 | unowned List last_item=first_item; 355 | 356 | for (item_it = first_item; item_it != null; item_it = item_it.next) { 357 | unowned HVBoxItem item = item_it.data; 358 | unowned Widget widget = item.widget; 359 | var m_h =0; 360 | var n_h =0; 361 | 362 | widget.get_preferred_width (out allocation.width, out natural_width); 363 | widget.get_preferred_height(out m_h,out n_h); 364 | 365 | minimum_height=int.max(minimum_height,m_h); 366 | natural_height=int.max(natural_height,n_h); 367 | 368 | if( (sum_w + allocation.width) > width) 369 | break;//normal out 370 | 371 | sum_w += allocation.width; 372 | last_item=item_it; 373 | } 374 | 375 | first_item=last_item; 376 | return (get_max_natural_height == true ? natural_height : minimum_height); 377 | }//get_line_height 378 | 379 | private int get_allocated_line_height (ref unowned List first_item=null,int width) { 380 | 381 | if(first_item==null) 382 | return -1;//assert 383 | 384 | int allocated_height = 0; 385 | int allocated_width = 0; 386 | var sum_w=0; 387 | 388 | 389 | unowned List item_it=null; 390 | unowned List last_item=first_item; 391 | 392 | for (item_it = first_item; item_it != null; item_it = item_it.next) { 393 | unowned HVBoxItem item = item_it.data; 394 | unowned Widget widget = item.widget; 395 | 396 | allocated_width = widget.get_allocated_width(); 397 | 398 | allocated_height = int.max(allocated_height, widget.get_allocated_height()); 399 | 400 | if( (sum_w + allocated_width) > width) 401 | break;//normal out 402 | 403 | sum_w += allocated_width; 404 | last_item=item_it; 405 | } 406 | 407 | first_item=last_item; 408 | return allocated_height; 409 | }//get_line_height 410 | 411 | 412 | public override void size_allocate (Gtk.Allocation allocation) { 413 | //this.update_size(); 414 | 415 | debug("size_allocate x=%d y=%d w=%d h=%d\n",allocation.x,allocation.y,allocation.width,allocation.height); 416 | 417 | Gtk.StyleContext context = this.get_style_context(); 418 | Gtk.Border border=context.get_border(StateFlags.NORMAL); 419 | //original allocation values 420 | var pos_x=allocation.x; 421 | var orig_pos_x = allocation.x; 422 | var orig_pos_y = allocation.y; 423 | var orig_pos_h = allocation.height; 424 | var orig_pos_w = allocation.width; 425 | var orig_pos_w_max = orig_pos_w-border.left-border.right; 426 | var sum_w=0; 427 | var line_h=0; 428 | 429 | unowned List item_it=null; 430 | unowned List end_of_line=null; 431 | 432 | for (item_it = this.children; item_it != null; item_it = item_it.next) { 433 | 434 | end_of_line=item_it; 435 | line_h = get_line_height(ref end_of_line,orig_pos_w_max,false); 436 | if(line_h<0){ 437 | debug("Something wrong!"); 438 | break; 439 | } 440 | allocation.x = orig_pos_x+border.left ;//start of line 441 | allocation.height=line_h;//base height for line 442 | 443 | unowned List line_item=item_it; 444 | 445 | 446 | for (line_item=item_it; (line_item != null && end_of_line != null) && 447 | line_item != end_of_line.next ; line_item = line_item.next) { 448 | 449 | unowned HVBoxItem item = line_item.data; 450 | unowned Widget widget = item.widget; 451 | 452 | var ingnore_h = 0; 453 | widget.get_preferred_width (out allocation.width, out ingnore_h); 454 | 455 | if(allocation.width>orig_pos_w_max){ 456 | widget.width_request=orig_pos_w_max;//set width_request (maximum width) for VTToggleButton 457 | widget.get_preferred_width (out allocation.width, out ingnore_h);//now width shuld be limited to the maximum 458 | if(allocation.width>orig_pos_w_max) 459 | allocation.width=orig_pos_w_max;//just ensure that width is limited 460 | }else 461 | if(allocation.width0){ 462 | widget.width_request=-1;//reset maximum width 463 | widget.get_preferred_width (out allocation.width, out ingnore_h);//now width shuld be unlimited 464 | } 465 | 466 | if(!item.ignore)//skip but remember size 467 | widget.size_allocate(allocation); 468 | allocation.x+=allocation.width; 469 | }//end of line 470 | allocation.y += line_h;//next line pos 471 | item_it = end_of_line; 472 | } 473 | if(minimize_size) 474 | allocation.height = allocation.y-orig_pos_y; 475 | else 476 | allocation.height = orig_pos_h; 477 | allocation.height+=border.bottom; 478 | allocation.x = orig_pos_x; 479 | allocation.y = orig_pos_y; 480 | allocation.width = orig_pos_w; 481 | base.size_allocate (allocation);//allocate container it self 482 | } 483 | 484 | public override SizeRequestMode get_request_mode () { 485 | return (this.mode); 486 | } 487 | 488 | 489 | public override void get_preferred_width (out int o_minimum_width, out int o_natural_width) { 490 | var sum_w = 0; 491 | var max_w = 0; 492 | foreach(unowned HVBoxItem item in this.children){ 493 | unowned Widget widget = item.widget; 494 | widget.get_preferred_width (out o_minimum_width, out o_natural_width); 495 | max_w=int.max(o_minimum_width,max_w); 496 | sum_w+=o_minimum_width; 497 | } 498 | o_minimum_width=max_w; 499 | o_natural_width=sum_w; 500 | if(this.width_request>0 && sum_w>this.width_request){//limit max child widget size 501 | o_minimum_width=o_natural_width=this.width_request; 502 | } 503 | //debug("get_preferred_width self_nat=%d self_min=%d minimum=%d natural=%d\n",this.self_natural_width,this.self_minimum_width,o_minimum_width,o_natural_width); 504 | } 505 | 506 | private void _get_preferred_height_for_width (int width, out int minimum_height, out int natural_height) { 507 | 508 | unowned List item_it=null; 509 | unowned List end_of_line=null; 510 | Gtk.StyleContext context = this.get_style_context(); 511 | Gtk.Border border=context.get_border(StateFlags.NORMAL); 512 | for (item_it = this.children; item_it != null; item_it = item_it.next) { 513 | 514 | end_of_line=item_it; 515 | minimum_height += get_line_height(ref end_of_line, width-border.left-border.right,false); 516 | end_of_line=item_it; 517 | natural_height += get_line_height(ref end_of_line,width-border.left-border.right,true); 518 | item_it = end_of_line; 519 | } 520 | 521 | } 522 | 523 | public override void get_preferred_height_for_width (int width,out int minimum_height, out int natural_height) { 524 | hvbox_get_preferred_height_for_width (width,out minimum_height, out natural_height); 525 | } 526 | public void hvbox_get_preferred_height_for_width (int width,out int minimum_height, out int natural_height) { 527 | 528 | this._get_preferred_height_for_width(width,out minimum_height, out natural_height); 529 | 530 | Gtk.StyleContext context = this.get_style_context(); 531 | Gtk.Border border=context.get_border(StateFlags.NORMAL); 532 | minimum_height+=border.bottom; 533 | natural_height+=border.bottom; 534 | //debug("get_preferred_height_for_width=%d != %d self_min=%d minimum=%d natural=%d\n",width,this.self_natural_width,this.self_minimum_width,minimum_height,natural_height); 535 | } 536 | 537 | 538 | /* 539 | * width for heigth not yet supported 540 | * 541 | * public override void get_preferred_width_for_height (int height,out int minimum_width, out int natural_width) { 542 | var sum_w = 0; 543 | foreach(unowned HVBoxItem item in this.children){ 544 | Widget widget = item.widget; 545 | widget.get_preferred_width (out minimum_width,out natural_width); 546 | sum_w+=minimum_width; 547 | } 548 | if(minimum_width>this.self_width){ 549 | minimum_width=(int)(sum_w/((int)(height/28))); 550 | }else{ 551 | minimum_width=this.self_width; 552 | } 553 | natural_width=minimum_width; 554 | //~ debug("get_preferred_width_for_height=%d minimum=%d natural=%d\n",height,minimum_width,natural_width); 555 | } 556 | 557 | 558 | public override void get_preferred_height (out int minimum_height, out int natural_height) { 559 | natural_height=minimum_height=28; 560 | }*/ 561 | 562 | public override void forall_internal(bool include_internal,Gtk.Callback callback){ 563 | //unowned 564 | //foreach(HVBoxItem item in this.children){ 565 | unowned List item_it=null; 566 | if(this.children != null) 567 | for (item_it = this.children; this.children !=null && item_it != null; item_it = item_it.next) { 568 | unowned HVBoxItem item = item_it.data; 569 | if(item.widget!=null && (item.widget is Gtk.Widget)){ 570 | unowned Widget widget = item.widget; 571 | if(item!=null && !item.ignore && widget!=null) //ignore dnd window 572 | callback(widget); 573 | } 574 | } 575 | } 576 | 577 | public override void add (Widget w){ 578 | this.insert (w, -1); 579 | } 580 | 581 | public void insert (Widget w, int index){ 582 | debug("inser at %d\n",index); 583 | unowned Widget widget = w; 584 | widget.set_parent(this); 585 | HVBoxItem item = new HVBoxItem(widget); 586 | 587 | drag_source_set (widget, Gdk.ModifierType.BUTTON1_MASK, target_entries, Gdk.DragAction.MOVE); 588 | 589 | item.drag_begin_id = widget.drag_begin.connect ((context) => { 590 | if(dnd_inprocess)return; 591 | dnd_inprocess=true; 592 | debug ("drag begin"); 593 | this.last_dnd_x=-1;//reset position 594 | this.last_dnd_y=-1;//reset position 595 | this.last_dnd_item=item; 596 | this.last_dnd_above_item=item; 597 | //~ drag_highlight (widget); 598 | widget.unparent (); 599 | 600 | dnd_window = new Window (WindowType.POPUP); 601 | dnd_window.name="HVBox_dnd_window"; 602 | dnd_window.set_screen(widget.get_screen()); 603 | dnd_window.add (widget); 604 | dnd_window.show(); 605 | 606 | item.ignore=true; 607 | 608 | dnd_window.draw.connect ((cr)=>{widget.draw(cr); return true;}); 609 | 610 | drag_set_icon_widget(context, dnd_window, (widget.get_allocated_width()/2), (widget.get_allocated_height()/2)); 611 | //this.update_size(); 612 | debug ("drag begin2"); 613 | //~ base.drag_begin(context) ; 614 | }); 615 | 616 | item.drag_data_get_id = widget.drag_data_get.connect ((context, selection_data, info, time) => { 617 | debug ("drag data get"); 618 | Gdk.Atom target = Gdk.Atom.intern_static_string ("GTK_HVBOX_ITEM"); 619 | 620 | if(selection_data.get_target () == target){ 621 | //workaround for vala 0.14 selection_data.set uchar[] 622 | uchar[] adata = new uchar[sizeof(void *)];//should work on x86_64 too 623 | ulong* pdata = (ulong *)(&adata[0]);//should work on x86_64 too 624 | HVBoxItem** pitem=&item;//should work on x86_64 too 625 | *pdata=pitem; 626 | selection_data.set (target,8,(uchar[])adata); 627 | //~ base.drag_data_get(context, selection_data, info, time) ; 628 | } 629 | }); 630 | 631 | item.drag_end_id = widget.drag_end.connect ((context) => { 632 | debug ("drag end"); 633 | this.last_dnd_item=null; 634 | this.last_dnd_above_item=null; 635 | dnd_window.remove (widget); 636 | widget.set_parent (this); 637 | dnd_window.destroy(); 638 | item.ignore=false; 639 | drag_end(context); 640 | dnd_inprocess=false; 641 | this.child_reordered(item.widget,this.children.index(item)); 642 | }); 643 | 644 | children.insert(item,index); 645 | 646 | this.queue_resize(); 647 | } 648 | 649 | public override void remove (Widget widget){ 650 | debug("remove\n"); 651 | foreach(unowned HVBoxItem item in this.children){ 652 | if(item.widget == widget){ 653 | item.widget.unparent(); 654 | GLib.SignalHandler.disconnect(item.widget,item.drag_begin_id); 655 | GLib.SignalHandler.disconnect(item.widget,item.drag_data_get_id); 656 | GLib.SignalHandler.disconnect(item.widget,item.drag_end_id); 657 | children.remove(item); 658 | 659 | if(children.length()>0 && this.visible){ 660 | int minimum_height,natural_height; 661 | hvbox_get_preferred_height_for_width(this.get_allocated_width(),out minimum_height, out natural_height); 662 | this.queue_resize();//and redraw 663 | } 664 | //item.unref();//destroy 665 | break; 666 | //possible problem not optimized exit 667 | //~ item.destroy(); 668 | //~ return; 669 | } 670 | } 671 | } 672 | 673 | public int children_index (Widget? widget){ 674 | if(widget is Gtk.Widget) 675 | foreach( HVBoxItem item in this.children){ 676 | if (item.widget==widget) 677 | return children.index(item) ; 678 | } 679 | 680 | return -1; 681 | } 682 | 683 | public unowned Widget children_nth (int index){ 684 | debug("Get_from_index\n"); 685 | HVBoxItem item = children.nth_data(index); 686 | if(item != null) 687 | return item.widget; 688 | else 689 | return null; 690 | } 691 | 692 | public unowned Widget children_last (){ 693 | debug("children_last\n"); 694 | HVBoxItem item = children.last().data; 695 | if(item != null) 696 | return item.widget; 697 | else 698 | return null; 699 | 700 | } 701 | public void place_before(Widget before,Widget what){ 702 | unowned List item_it=null; 703 | int b_index=this.children_index(before); 704 | int w_index=this.children_index(what); 705 | debug("place_before bef=%d what=%d\n",b_index,w_index); 706 | if(b_index>=0 && w_index>=0){ 707 | debug("place_before bef=%d what=%d\n",b_index,w_index); 708 | item_it= children.nth(b_index); 709 | HVBoxItem bdata=children.nth_data(w_index) ; 710 | this.children.remove(bdata); 711 | this.children.insert_before(item_it,bdata); 712 | } 713 | //else{}//shouldnot happens! 714 | } 715 | public void place_on_index(Widget what,int new_index){ 716 | unowned List item_it=null; 717 | int w_index=this.children_index(what); 718 | 719 | if(w_index!=new_index){ 720 | debug("place_on_index w_index=%d new_index=%d\n",w_index,new_index); 721 | //item_it= children.nth(a_index); 722 | HVBoxItem bdata=children.nth_data(w_index) ; 723 | this.children.remove(bdata); 724 | this.children.insert(bdata,new_index); 725 | } 726 | } 727 | 728 | /*public new void propagate_draw (Gtk.Widget child, Cairo.Context cr) { 729 | //draw line between child widgets 730 | var dest_x =0; 731 | var dest_y =0; 732 | child.translate_coordinates (this, 0, 0, out dest_x, out dest_y); 733 | cr.set_line_width (1.0); 734 | cr.set_line_join (LineJoin.ROUND); 735 | cr.move_to(dest_x+child.get_allocated_width(),dest_y); 736 | cr.line_to(dest_x+child.get_allocated_width(), dest_y+child.get_allocated_height()); 737 | cr.stroke (); 738 | //cr.set_source_rgba (1.0, 0.0, 0.0, 1); 739 | base.propagate_draw (child, cr); 740 | }*/ 741 | public override bool draw (Cairo.Context cr){ 742 | //~ Globals.print_backtrace(); 743 | if(!this.get_realized()){ 744 | debug("draw invisible\n"); 745 | return false;//prevent X Window System error 746 | } 747 | if(this.children.length()<1){ 748 | return base.draw(cr); 749 | } 750 | int width = this.get_allocated_width (); 751 | int height = this.get_allocated_height (); 752 | debug("draw\n"); 753 | cr.save (); 754 | 755 | Gtk.StyleContext context = this.get_style_context(); 756 | context.save(); 757 | Gtk.Border border=context.get_border(StateFlags.NORMAL); 758 | 759 | var line_h = 0; 760 | var allocation = Gtk.Allocation();//don't use new for struct 761 | 762 | allocation.x=0; 763 | allocation.y=0; 764 | allocation.height=0; 765 | allocation.width=0; 766 | 767 | int[] arr_w = {}; 768 | int[] arr_h = {}; 769 | 770 | if(!background_only_behind_widgets){ 771 | context.render_background(cr, 0, 0,width, height); 772 | context.render_frame(cr,0, 0, width, height); 773 | } 774 | 775 | var color = context.get_background_color(StateFlags.NORMAL); 776 | cr.set_source_rgba (color.red,color.green,color.blue,color.alpha);//background 777 | 778 | unowned List item_it=null; 779 | unowned List end_of_line=null; 780 | bool found_dnd_above=false; 781 | //draw background only behind widgets 782 | for (item_it = this.children; item_it != null; item_it = item_it.next) { 783 | 784 | end_of_line=item_it; 785 | line_h = get_allocated_line_height(ref end_of_line, width-border.left-border.right);//get end of line 786 | 787 | allocation.x = 0 ;//start of the line 788 | allocation.height=line_h;//base height for line 789 | allocation.width=0; 790 | unowned List line_item=item_it; 791 | 792 | for (line_item=item_it; (line_item != null && end_of_line != null) && 793 | line_item != end_of_line.next ; line_item = line_item.next) { 794 | unowned HVBoxItem item = line_item.data; 795 | unowned Widget widget = item.widget; 796 | allocation.width+=item.widget.get_allocated_width(); 797 | //dnd stuff 798 | if( !found_dnd_above && dnd_inprocess && this.last_dnd_x>0 && this.last_dnd_x list = app.get_windows(); 261 | if(list!=null){ 262 | var win=((VTMainWindow)list.data); 263 | return win.title; 264 | } 265 | return "window not found :("; 266 | } 267 | } 268 | [DBus (name = "org.gtk.altyo")] 269 | interface AltYoDbusClient : Object { 270 | public abstract string get_window_title () throws IOError; 271 | } 272 | 273 | public class AppAltYo: Gtk.Application { 274 | public AppAltYo(string? application_id, ApplicationFlags flags){ 275 | Object (application_id:application_id, flags:flags); 276 | } 277 | //CCode for vala 0.18 (backport from vala 0.22) 278 | //prevent segmentation fault if compiled with valac 0.18 279 | public override bool local_command_line ([CCode (array_length = false, array_null_terminated = true)]ref unowned string[] arguments, out int exit_status){ 280 | exit_status=-1; 281 | return false; 282 | } 283 | /* glib compatability hack 284 | * http://www.trevorpounds.com/blog/?p=103 285 | * >Building and linking to an older version of libc or using a chroot is a much better, less error prone approach. 286 | * */ 287 | //~[CCode (cname = "__asm__(\".symver memcpy,memcpy@GLIBC_2.2.5\");//",type="")] 288 | //~ public extern void* fake_function(); 289 | #if VALA_0_22 290 | //if > GLib.Version.@2_34 291 | public override bool dbus_register (DBusConnection connection, string object_path){ 292 | try { 293 | connection.register_object (object_path, new AltYoDbusServer (this)); 294 | } catch (IOError e) { 295 | GLib.stderr.printf ("Could not register AltYoServer\n"); 296 | } 297 | return true;//continue 298 | } 299 | #endif 300 | } 301 | 302 | public delegate void myprintcb (string print_string); 303 | 304 | int apply_flags(VTMainWindow remote_window,myprintcb myprint){ 305 | int return_code=0; 306 | 307 | if(Globals.force_debug){ 308 | configure_debug(remote_window.conf); 309 | } 310 | 311 | if(Globals.reload){ 312 | remote_window.conf.load_config(); 313 | } 314 | 315 | if(Globals.path!=null){ 316 | remote_window.conf.default_path=Globals.path; 317 | } 318 | 319 | if(Globals.exec_file_with_args!=null){ 320 | foreach(var s in Globals.exec_file_with_args){ 321 | debug("exec %s",s); 322 | remote_window.ayobject.add_tab_with_title(s,s); 323 | } 324 | 325 | if(remote_window.current_state == WStates.HIDDEN) 326 | remote_window.pull_down(); 327 | } 328 | 329 | if(Globals.toggle){ 330 | remote_window.toggle_window(); 331 | } 332 | 333 | if(Globals.cmd_fullscreen){ 334 | if(remote_window.maximized) 335 | remote_window.maximized=false; 336 | else 337 | remote_window.maximized=true; 338 | } 339 | 340 | if(remote_window.conf.get_boolean("window_allow_remote_control",false)){ 341 | if(Globals.cmd_title_tab!=null){ 342 | var current_index=remote_window.ayobject.cmd_get_tab_index(); 343 | var count=remote_window.ayobject.cmd_get_tabs_count(); 344 | if(Globals.cmd_title_tab!=""){ 345 | var s_arr = Globals.cmd_title_tab.split (":",2); 346 | uint64 index=0;/*index from user starting from 1*/ 347 | if(s_arr.length==2 && uint64.try_parse(s_arr[0],out index) && index<=count && index>0){ 348 | if(s_arr[1]=="") s_arr[1]=null; 349 | myprint("altyo: new title=%d:%s\n".printf((int)index,s_arr[1])); 350 | remote_window.ayobject.cmd_set_tab_title((uint)index-1,s_arr[1]); 351 | }else{ 352 | if(s_arr.length!=2) 353 | myprint("altyo usage:\n\t-t \"3:new title\"\n\t-t \"\"\n"); 354 | 355 | if(index>count) 356 | myprint("altyo: Err index>count (%d > %d)\n".printf((int)index,(int)count) ); 357 | if(index==0) 358 | myprint("altyo: Err index must be > 1\n"); 359 | return_code=1; 360 | } 361 | }else{ 362 | myprint("%d/%d \n".printf(current_index+1,(int)count) ); 363 | for(var i=0; i0 ){ 373 | remote_window.ayobject.cmd_activate_tab((uint)(index-1)); 374 | debug("altyo: selected %d\n".printf((int)index) ); 375 | }else{ 376 | if(index>count) 377 | myprint("altyo: Err index>count (%d > %d)\n".printf((int)index,(int)count) ); 378 | if(index==0) 379 | myprint("altyo: Err index must be > 1\n"); 380 | return_code=1; 381 | } 382 | } 383 | 384 | if(Globals.cmd_close_tab!=null){ 385 | var count=remote_window.ayobject.cmd_get_tabs_count(); 386 | uint64 index=0;/*index from user starting from 1*/ 387 | if(uint64.try_parse(Globals.cmd_close_tab,out index) && index<=count && index>0 ){ 388 | remote_window.ayobject.close_tab((int)(index-1)); 389 | debug("altyo: tab %d closed\n".printf((int)index) ); 390 | }else{ 391 | if(index>count) 392 | myprint("altyo: Err index>count (%d > %d)\n".printf((int)index,(int)count) ); 393 | if(index==0) 394 | myprint("altyo: Err index must be > 1\n"); 395 | return_code=1; 396 | } 397 | } 398 | }//if window_allow_remote_control 399 | else{ 400 | if(Globals.cmd_title_tab!=null || Globals.cmd_select_tab!=null || Globals.cmd_close_tab!=null) 401 | myprint("altyo: Err remote commands is disabled in configuration file!\n"); 402 | return_code=1; 403 | } 404 | return return_code; 405 | } 406 | 407 | int main (string[] args) { 408 | 409 | GLib.ApplicationFlags appflags=ApplicationFlags.HANDLES_COMMAND_LINE; 410 | 411 | Intl.setlocale (LocaleCategory.ALL, ""); 412 | Intl.bindtextdomain (GETTEXT_PACKAGE, null); 413 | Intl.bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); 414 | Intl.textdomain (GETTEXT_PACKAGE); 415 | 416 | //Gtk.init (ref args); 417 | Globals.app_id=DEFAULT_APP_ID;//default app id 418 | Globals.remote_cwd = GLib.Environment.get_current_dir(); 419 | /* Parse only --id and --standalone options 420 | * others will be parsed in application app.startup.connect event 421 | * */ 422 | OptionContext local_ctx = new OptionContext("AltYo");//global var, used in app.startup 423 | try { 424 | local_ctx.add_main_entries(Globals.options, null); 425 | string[] args2 = args; //copy args for local use, original args will be used on remote side 426 | unowned string[] args3 = args2;//tmp pointer 427 | 428 | local_ctx.parse(ref args3); 429 | args2=null; 430 | 431 | var self_basename = GLib.Path.get_basename(args[0]); 432 | 433 | if( self_basename != "altyo" || Globals.xterm_mode){ 434 | Globals.xterm_mode = true; 435 | Globals.x_terminal_emulator_exec(ref args); 436 | GLib.stderr.printf("AltYo runnied as %s in xterm mode\n",self_basename); 437 | } 438 | } catch (Error e) { 439 | GLib.stderr.printf("Error initializing: %s\n", e.message); 440 | return 1; 441 | } 442 | 443 | if(Globals.opt_version){ 444 | printf("altyo %s \nLicense GPLv3+\n",(AY_CHANGELOG_TAG!="" ? AY_CHANGELOG_TAG : "0.4") +" "+AY_GIT_HASH ); 445 | Posix.exit(0); 446 | } 447 | 448 | #if VALA_0_22 449 | /*searching for remote instances*/ 450 | if(Globals.list_id){ 451 | Variant interfaces; 452 | DBusConnection session_bus = Bus.get_sync (BusType.SESSION); 453 | try { 454 | interfaces = session_bus.call_sync ("org.freedesktop.DBus", 455 | "/", 456 | "org.freedesktop.DBus", 457 | "ListNames", 458 | null, 459 | new VariantType ("(as)"), 460 | DBusCallFlags.NONE, 461 | -1); 462 | }catch (GLib.Error e) { 463 | GLib.stderr.printf ("unable to search for existing altyo instances: %s \n", e.message); 464 | return 1; 465 | } 466 | 467 | foreach (var val in interfaces.get_child_value (0)) { 468 | var address = (string) val; 469 | if (address.has_prefix (DEFAULT_APP_ID)){//search only inside org.gtk.altyo 470 | printf("%s",address); 471 | try{ 472 | string path = "/"+address.replace(".","/"); 473 | AltYoDbusClient client = session_bus.get_proxy_sync (address,path, 474 | GLib.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS|GLib.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES); 475 | printf(" %s",client.get_window_title()); 476 | }catch (GLib.Error e) { 477 | //GLib.stderr.printf ("unable to search for existing altyo instances: %d %s \n",e.code, e.message); 478 | } 479 | printf("\n"); 480 | } 481 | } 482 | 483 | return 0;//list and exit 484 | } 485 | #endif 486 | 487 | if(Globals.standalone_mode && Globals.app_id==DEFAULT_APP_ID){ 488 | Globals.app_id+="._%d".printf(Posix.getpid());//generate unique id for standalone_mode 489 | } 490 | if(!Globals.app_id.has_prefix(DEFAULT_APP_ID)){ 491 | /*this name restriction occur because we need limit searching in --listid */ 492 | printf(_("Application id must begin with %s \n for example %s.my_instance\n"),DEFAULT_APP_ID,DEFAULT_APP_ID); 493 | return 1; 494 | } 495 | 496 | if(Globals.app_id == "none") 497 | Globals.app_id=null; 498 | else if(!GLib.Application.id_is_valid(Globals.app_id)){ 499 | printf(_("Wrong application id \"%s\""),Globals.app_id); 500 | printf(_(""" 501 | Application identifiers must contain only the ASCII characters "A-Z[0-9]_-." and must not begin with a digit. 502 | Application identifiers must contain at least one '.' (period) character (and thus at least three elements). 503 | Application identifiers must not begin or end with a '.' (period) character. 504 | Application identifiers must not contain consecutive '.' (period) characters. 505 | Application identifiers must not exceed 255 characters.""")); 506 | return 1;//stop on error 507 | } 508 | 509 | if(Globals.standalone_mode){ 510 | Globals.disable_hotkey=true; 511 | } 512 | 513 | /******************************************************************/ 514 | /* use file as special configuration marker 515 | * because we should not parse config.ini file yet 516 | * later we will sync it in sync_workaround() 517 | * simple and fast 518 | * */ 519 | string file_workaround_if_focuslost = GLib.Environment.get_user_config_dir()+"/altyo/workaround_if_focuslost"; 520 | if(GLib.FileUtils.test(file_workaround_if_focuslost,GLib.FileTest.EXISTS) ){ 521 | /* more info in README.md in FAQ. 522 | * */ 523 | if(!GLib.Environment.set_variable("GDK_CORE_DEVICE_EVENTS","1",true)) //must be set before new AppAltYo() 524 | printf("altyo: Unable to set GDK_CORE_DEVICE_EVENTS=1\n"); 525 | else if(Globals.force_debug) 526 | printf("altyo: set GDK_CORE_DEVICE_EVENTS=1\n"); 527 | } 528 | /******************************************************************/ 529 | 530 | var app = new AppAltYo(Globals.app_id, appflags); 531 | 532 | //remote args usage 533 | app.command_line.connect((command_line)=>{//ApplicationCommandLine 534 | 535 | if(!command_line.get_is_remote() )//local command line was handled in app.startup 536 | return 0;//just ignore it 537 | 538 | string[] argv = command_line.get_arguments(); 539 | debug("app.command_line.connect argv.length=%d %s",argv.length,argv[0]); 540 | OptionContext ctx = new OptionContext("AltYo"); 541 | ctx.add_main_entries(Globals.options, null); 542 | 543 | if(argv.length==1 ){//no parameters 544 | unowned List list = app.get_windows(); 545 | if(list!=null) 546 | ((VTMainWindow)list.data).pull_down(); //another altyo already running, show it 547 | return 0;//ok 548 | }else{ 549 | ctx.set_help_enabled (false);//disable exit from application if wrong parameters 550 | unowned string[] pargv=argv; 551 | Globals.exec_file_with_args=null;//clear array 552 | Globals.cmd_conf_file=null; 553 | Globals.reload=false; 554 | Globals.opt_help=false; 555 | Globals.toggle=false; 556 | Globals.path=null; 557 | Globals.force_debug=false; 558 | 559 | Globals.cmd_fullscreen = false; 560 | Globals.cmd_title_tab = null; 561 | Globals.cmd_select_tab = null; 562 | Globals.cmd_close_tab = null; 563 | Globals.remote_cwd = command_line.get_cwd(); 564 | Globals.xterm_mode = false; 565 | 566 | var old_standalone_mode=Globals.standalone_mode; 567 | try { 568 | if(!ctx.parse(ref pargv))return 3; 569 | } catch (Error e) { 570 | command_line.print("altyo: Error initializing: %s\n", e.message); 571 | } 572 | Globals.standalone_mode=old_standalone_mode;//restore standalone_mode state 573 | 574 | var self_basename = GLib.Path.get_basename(argv[0]); 575 | 576 | if( self_basename != "altyo" || Globals.xterm_mode){ 577 | Globals.xterm_mode = true; 578 | string[] argv2 = command_line.get_arguments(); 579 | unowned string[] argv3 = argv2; 580 | Globals.x_terminal_emulator_exec (ref argv3); 581 | debug("AltYo runnied as %s in xterm mode\n",self_basename); 582 | argv2=null; 583 | }else 584 | Globals.xterm_mode = false; 585 | 586 | debug("app.command_line.connect reload=%d",(int)Globals.reload); 587 | VTMainWindow remote_window=null; 588 | unowned List list = app.get_windows(); 589 | if(list!=null) 590 | remote_window=((VTMainWindow)list.data); 591 | else{ 592 | command_line.print("altyo: Err remote window not found\n"); 593 | return 2; 594 | } 595 | 596 | var return_code = apply_flags(remote_window,(s)=>{ 597 | command_line.print(s); 598 | }); 599 | 600 | Globals.reload=false; 601 | 602 | return return_code;//exit status 603 | } 604 | });//app.command_line.connect 605 | 606 | app.startup.connect(()=>{//first run 607 | if(Globals.force_remote){ 608 | printf("altyo: remote instance %s not found!\n",Globals.app_id); 609 | Posix.exit(1); 610 | } 611 | debug("app.startup.connect"); 612 | var conf = new MySettings(Globals.cmd_conf_file,Globals.standalone_mode); 613 | conf.readonly=Globals.config_readonly; 614 | conf.disable_hotkey=Globals.disable_hotkey; 615 | conf.default_path=Globals.path; 616 | conf.force_debug=Globals.force_debug; 617 | 618 | if(!conf.opened){ 619 | printf("altyo: Unable to open configuration file!\n"); 620 | Posix.exit(1); 621 | } 622 | 623 | conf.get_boolean("window_allow_remote_control",false);//remember option type 624 | 625 | configure_debug(conf); 626 | sync_workaround(conf,file_workaround_if_focuslost); 627 | 628 | debug("git_hash=%s",AY_GIT_HASH); 629 | debug("changelog_tag=%s",AY_CHANGELOG_TAG); 630 | 631 | conf.on_load.connect(()=>{ 632 | configure_debug(conf); 633 | sync_workaround(conf,file_workaround_if_focuslost); 634 | }); 635 | 636 | var win = new VTMainWindow (WindowType.TOPLEVEL); 637 | win.set_application(app); 638 | win.CreateVTWindow(conf); 639 | main_win=win; 640 | 641 | apply_flags(win,(s)=>{print(s);}); 642 | 643 | sigaction_t action = sigaction_t (); 644 | action.sa_handler = signal_handler; 645 | /* Hook up signal handlers */ 646 | sigaction (SIGINT, action, null); 647 | sigaction (SIGQUIT, action, null); 648 | //sigaction (SIGABRT, action, null);//something wrong! don't save file 649 | sigaction (SIGTERM, action, null); 650 | sigaction (SIGKILL, action, null); 651 | Gtk.main (); 652 | 653 | });//app.startup.connect 654 | var status = app.run(args); 655 | 656 | return status; 657 | } 658 | -------------------------------------------------------------------------------- /po/altyo.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2017-12-05 23:02+0300\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=CHARSET\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: main.vala:92 21 | msgid "Reload configuration" 22 | msgstr "" 23 | 24 | #: main.vala:93 25 | msgid "Read configuration from file" 26 | msgstr "" 27 | 28 | #: main.vala:93 29 | msgid "/path/to/config.ini" 30 | msgstr "" 31 | 32 | #: main.vala:95 main.vala:96 33 | msgid "Run command in new tab" 34 | msgstr "" 35 | 36 | #: main.vala:95 main.vala:96 37 | msgid "\"command arg1 argN...\"" 38 | msgstr "" 39 | 40 | #: main.vala:97 41 | msgid "Show/hide window" 42 | msgstr "" 43 | 44 | #: main.vala:98 45 | msgid "Set application id, none means disable application id" 46 | msgstr "" 47 | 48 | #: main.vala:99 49 | msgid "Show ids of running AltYo instances" 50 | msgstr "" 51 | 52 | #: main.vala:100 53 | msgid "Disable main hotkey" 54 | msgstr "" 55 | 56 | #: main.vala:101 57 | msgid "Disable control of window dimension" 58 | msgstr "" 59 | 60 | #: main.vala:102 61 | msgid "Set/update default path. Without arguments CWD will be used." 62 | msgstr "" 63 | 64 | #: main.vala:103 65 | msgid "Lock any configuration changes" 66 | msgstr "" 67 | 68 | #: main.vala:104 69 | msgid "Force debug" 70 | msgstr "" 71 | 72 | #: main.vala:105 73 | msgid "Toggle AltYo in fullscreen mode" 74 | msgstr "" 75 | 76 | #: main.vala:107 77 | msgid "Get/Set tab title" 78 | msgstr "" 79 | 80 | #: main.vala:109 81 | msgid "Select tab by index" 82 | msgstr "" 83 | 84 | #: main.vala:110 85 | msgid "Close tab by index" 86 | msgstr "" 87 | 88 | #: main.vala:111 89 | msgid "Connect to remote instance or exit." 90 | msgstr "" 91 | 92 | #: main.vala:112 93 | msgid "Display version number" 94 | msgstr "" 95 | 96 | #: main.vala:113 97 | msgid "Run in xterm compatibility mode" 98 | msgstr "" 99 | 100 | #: main.vala:472 101 | #, c-format 102 | msgid "" 103 | "Application id must begin with %s \n" 104 | " for example %s.my_instance\n" 105 | msgstr "" 106 | 107 | #: main.vala:479 108 | #, c-format 109 | msgid "Wrong application id \"%s\"" 110 | msgstr "" 111 | 112 | #: main.vala:480 113 | msgid "" 114 | "\n" 115 | " Application identifiers must contain only the ASCII characters \"A-" 116 | "Z[0-9]_-.\" and must not begin with a digit.\n" 117 | " Application identifiers must contain at least one '.' (period) character " 118 | "(and thus at least three elements).\n" 119 | " Application identifiers must not begin or end with a '.' (period) " 120 | "character.\n" 121 | " Application identifiers must not contain consecutive '.' (period) " 122 | "characters.\n" 123 | " Application identifiers must not exceed 255 characters." 124 | msgstr "" 125 | 126 | #: altyo_terminal.vala:464 127 | #, c-format 128 | msgid "tab_format wrong value! will be used default value. err:%s" 129 | msgstr "" 130 | 131 | #: altyo_terminal.vala:474 132 | #, c-format 133 | msgid "tab_title_format wrong value! will be used default value. err:%s" 134 | msgstr "" 135 | 136 | #: altyo_terminal.vala:482 137 | msgid "" 138 | "tab_title_format_regex odd value of array length! will be used default value." 139 | msgstr "" 140 | 141 | #: altyo_terminal.vala:489 142 | #, c-format 143 | msgid "tab_title_format_regex wrong value! will be used default value. err:%s" 144 | msgstr "" 145 | 146 | #: altyo_terminal.vala:803 147 | #, c-format 148 | msgid "" 149 | "terminal_exclude_variables wrong value! will be used default value. err:%s" 150 | msgstr "" 151 | 152 | #: altyo_terminal.vala:1050 153 | msgid "" 154 | "terminal_url_regexps odd value of array length! will be used default value." 155 | msgstr "" 156 | 157 | #: altyo_terminal.vala:1056 158 | #, c-format 159 | msgid "terminal_url_regexps wrong value! will be used default value. err:%s" 160 | msgstr "" 161 | 162 | #: altyo_terminal.vala:1241 163 | msgid "Quick settings" 164 | msgstr "" 165 | 166 | #: altyo_terminal.vala:1270 167 | msgid "Copy link" 168 | msgstr "" 169 | 170 | #: altyo_terminal.vala:1273 171 | msgid "Run link Ctrl+left mouse button" 172 | msgstr "" 173 | 174 | #: altyo_terminal.vala:1342 175 | msgid "Copy terminal name" 176 | msgstr "" 177 | 178 | #: altyo_terminal.vala:1356 179 | msgid "Copy terminal host name" 180 | msgstr "" 181 | 182 | #: altyo_terminal.vala:1370 183 | msgid "Copy running command" 184 | msgstr "" 185 | 186 | #: altyo_terminal.vala:1383 187 | msgid "Kill running command" 188 | msgstr "" 189 | 190 | #: altyo_terminal.vala:1390 191 | msgid "Do you really want to kill running command?" 192 | msgstr "" 193 | 194 | #: altyo_terminal.vala:1396 195 | msgid "Disable key bindings" 196 | msgstr "" 197 | 198 | #: altyo_terminal.vala:1403 199 | msgid "Disable terminal menu" 200 | msgstr "" 201 | 202 | #: altyo_terminal.vala:1432 203 | msgid "Terminal menu" 204 | msgstr "" 205 | 206 | #: altyo_window.vala:1145 207 | msgid "Please select key combination, to show/hide AltYo." 208 | msgstr "" 209 | 210 | #: altyo_window.vala:1147 211 | #, c-format 212 | msgid "Previous key '%s' incorrect or busy" 213 | msgstr "" 214 | 215 | #: altyo_window.vala:1156 216 | msgid "Press any key" 217 | msgstr "" 218 | 219 | #: altyo_window.vala:1161 220 | msgid "Grab another key." 221 | msgstr "" 222 | 223 | #: altyo_window.vala:1635 altyo_window.vala:1832 224 | msgid "Shell terminated." 225 | msgstr "" 226 | 227 | #: altyo_window.vala:1726 228 | msgid "Tab is locked, are you sure you want to close?" 229 | msgstr "" 230 | 231 | #: altyo_window.vala:1737 232 | #, c-format 233 | msgid "" 234 | "terminal_prevent_close_regex wrong value! will be used default value. err:%s" 235 | msgstr "" 236 | 237 | #: altyo_window.vala:1760 238 | #, c-format 239 | msgid "Found important task \"%s\"" 240 | msgstr "" 241 | 242 | #: altyo_window.vala:1761 243 | msgid "Close tab anyway?" 244 | msgstr "" 245 | 246 | #: altyo_window.vala:2030 247 | msgid "Really quit?" 248 | msgstr "" 249 | 250 | #: altyo_window.vala:2031 251 | msgid "Save session" 252 | msgstr "" 253 | 254 | #: altyo_window.vala:2067 255 | msgid "willemw12@gmail.com" 256 | msgstr "" 257 | 258 | #: altyo_window.vala:2088 259 | #, c-format 260 | msgid "" 261 | "Really reset to defaults?\n" 262 | "Current settings will be saved in backup file %s.bak" 263 | msgstr "" 264 | 265 | #: altyo_window.vala:2130 266 | msgid "Setup custom title?" 267 | msgstr "" 268 | 269 | #: altyo_window.vala:2132 270 | msgid "new custom title" 271 | msgstr "" 272 | 273 | #: altyo_window.vala:2189 274 | #, c-format 275 | msgid "" 276 | "You are trying to use key binding \"%s\"\n" 277 | "for action \"%s\"\n" 278 | "but, same key binding already binded to the action \"%s\"" 279 | msgstr "" 280 | 281 | #: altyo_window.vala:2190 282 | msgid "error" 283 | msgstr "" 284 | 285 | #: altyo_window.vala:2309 286 | msgid "New tab" 287 | msgstr "" 288 | 289 | #: altyo_window.vala:2309 290 | msgid "Open new tab" 291 | msgstr "" 292 | 293 | #: altyo_window.vala:2328 294 | msgid "Close tab" 295 | msgstr "" 296 | 297 | #: altyo_window.vala:2328 298 | msgid "Close current tab" 299 | msgstr "" 300 | 301 | #: altyo_window.vala:2333 302 | msgid "Next tab" 303 | msgstr "" 304 | 305 | #: altyo_window.vala:2333 306 | msgid "Switch to next tab" 307 | msgstr "" 308 | 309 | #: altyo_window.vala:2338 310 | msgid "Previous tab" 311 | msgstr "" 312 | 313 | #: altyo_window.vala:2338 314 | msgid "Switch to previous tab" 315 | msgstr "" 316 | 317 | #: altyo_window.vala:2344 318 | #, c-format 319 | msgid "Switch to tab %d" 320 | msgstr "" 321 | 322 | #: altyo_window.vala:2344 323 | #, c-format 324 | msgid "Switch to tab %d,double press switch to tab %d" 325 | msgstr "" 326 | 327 | #: altyo_window.vala:2372 328 | msgid "Copy" 329 | msgstr "" 330 | 331 | #: altyo_window.vala:2372 332 | msgid "Copy selected text" 333 | msgstr "" 334 | 335 | #: altyo_window.vala:2377 336 | msgid "Paste" 337 | msgstr "" 338 | 339 | #: altyo_window.vala:2377 340 | msgid "Paste from primary clipboard" 341 | msgstr "" 342 | 343 | #: altyo_window.vala:2381 344 | msgid "Copy all" 345 | msgstr "" 346 | 347 | #: altyo_window.vala:2381 348 | msgid "Copy all text" 349 | msgstr "" 350 | 351 | #: altyo_window.vala:2387 352 | msgid "Search" 353 | msgstr "" 354 | 355 | #: altyo_window.vala:2399 356 | msgid "Show/Hide Quick list" 357 | msgstr "" 358 | 359 | #: altyo_window.vala:2407 360 | msgid "Follow mouse cursor" 361 | msgstr "" 362 | 363 | #: altyo_window.vala:2410 364 | msgid "Settings..." 365 | msgstr "" 366 | 367 | #: altyo_window.vala:2410 368 | msgid "Settings" 369 | msgstr "" 370 | 371 | #: altyo_window.vala:2443 372 | msgid "AltYo Settings" 373 | msgstr "" 374 | 375 | #: altyo_window.vala:2467 376 | msgid "Quit" 377 | msgstr "" 378 | 379 | #: altyo_window.vala:2477 380 | msgid "Show/Hide" 381 | msgstr "" 382 | 383 | #: altyo_window.vala:2482 384 | msgid "About" 385 | msgstr "" 386 | 387 | #: altyo_window.vala:2486 388 | msgid "Disable sort tab" 389 | msgstr "" 390 | 391 | #: altyo_window.vala:2494 392 | msgid "Stay on top" 393 | msgstr "" 394 | 395 | #: altyo_window.vala:2505 396 | msgid "Stick" 397 | msgstr "" 398 | 399 | #: altyo_window.vala:2505 400 | msgid "Toggle stick" 401 | msgstr "" 402 | 403 | #: altyo_window.vala:2514 404 | msgid "Autohide" 405 | msgstr "" 406 | 407 | #: altyo_window.vala:2514 408 | msgid "Toggle autohide" 409 | msgstr "" 410 | 411 | #: altyo_window.vala:2518 412 | msgid "Maximize - restore" 413 | msgstr "" 414 | 415 | #: altyo_window.vala:2518 416 | msgid "Maximize window, or restore to normal size" 417 | msgstr "" 418 | 419 | #: altyo_window.vala:2527 420 | msgid "Sort by hostname" 421 | msgstr "" 422 | 423 | #: altyo_window.vala:2531 424 | msgid "Open new window" 425 | msgstr "" 426 | 427 | #: altyo_window.vala:2576 428 | msgid "Search in terminals titles" 429 | msgstr "" 430 | 431 | #: altyo_window.vala:2587 432 | msgid "Terminal quick settings" 433 | msgstr "" 434 | 435 | #: altyo_window.vala:2592 436 | msgid "Lock tab" 437 | msgstr "" 438 | 439 | #: altyo_window.vala:2601 440 | msgid "Restore closed tab" 441 | msgstr "" 442 | 443 | #: altyo_window.vala:2601 444 | msgid "Restore last closed tab" 445 | msgstr "" 446 | 447 | #: altyo_window.vala:2609 448 | msgid "Custom title" 449 | msgstr "" 450 | 451 | #: altyo_window.vala:2616 452 | msgid "Show/Hide tabs" 453 | msgstr "" 454 | 455 | #: altyo_window.vala:2729 456 | #, c-format 457 | msgid "Tab%d - AltYo" 458 | msgstr "" 459 | 460 | #: altyo_window.vala:2805 461 | #, c-format 462 | msgid "" 463 | "terminal_session_exclude_regex wrong value! will be used default value. err:" 464 | "%s" 465 | msgstr "" 466 | 467 | #: altyo_window.vala:2904 468 | msgid "Restore tabs" 469 | msgstr "" 470 | 471 | #: altyo_window.vala:2911 472 | msgid "Restore all closed tabs" 473 | msgstr "" 474 | 475 | #: altyo_window.vala:2927 476 | #, c-format 477 | msgid "index %d" 478 | msgstr "" 479 | 480 | #: altyo_window.vala:3126 481 | msgid "Wrap search" 482 | msgstr "" 483 | 484 | #: altyo_window.vala:3138 485 | msgid "Match case-sensitive" 486 | msgstr "" 487 | 488 | #: altyo_window.vala:3154 489 | msgid "terminal text" 490 | msgstr "" 491 | 492 | #: altyo_window.vala:3169 493 | msgid "terminals titles" 494 | msgstr "" 495 | 496 | #: altyo_window.vala:3205 497 | msgid "Find previous" 498 | msgstr "" 499 | 500 | #: altyo_window.vala:3228 501 | msgid "Find next" 502 | msgstr "" 503 | 504 | #: altyo_window.vala:3241 505 | msgid "Close search dialog" 506 | msgstr "" 507 | 508 | #: altyo_window.vala:3446 509 | msgid "Apply" 510 | msgstr "" 511 | 512 | #: altyo_window.vala:3452 513 | msgid "Close dialog" 514 | msgstr "" 515 | 516 | #: altyo_settings.vala:430 517 | msgid "AYsettings" 518 | msgstr "" 519 | 520 | #: altyo_settings.vala:527 521 | msgid "Config is read only!" 522 | msgstr "" 523 | 524 | #: altyo_settings.vala:551 525 | msgid "AltYo attention" 526 | msgstr "" 527 | 528 | #: altyo_settings.vala:552 529 | msgid "You must restart altyo for the workaround to take effect." 530 | msgstr "" 531 | 532 | #: altyo_settings.vala:561 533 | msgid "px" 534 | msgstr "" 535 | 536 | #: altyo_settings.vala:564 537 | msgid "maximize" 538 | msgstr "" 539 | 540 | #: altyo_settings.vala:566 541 | msgid "%" 542 | msgstr "" 543 | 544 | #: altyo_settings.vala:980 545 | #, c-format 546 | msgid "in line %d at position %d error:%s" 547 | msgstr "" 548 | 549 | #: altyo_settings.vala:987 550 | msgid "Looks good" 551 | msgstr "" 552 | 553 | #: altyo_settings.vala:1648 554 | #, c-format 555 | msgid "" 556 | "New style will not be saved!\n" 557 | "in line %d at position %d\n" 558 | "error:%s" 559 | msgstr "" 560 | 561 | #: altyo_settings.vala:1650 562 | msgid "AltYo CSS style error" 563 | msgstr "" 564 | 565 | #: altyo_settings.vala:1698 altyo_settings.vala:1709 altyo_settings.vala:1754 566 | #, c-format 567 | msgid "AltYo %s error" 568 | msgstr "" 569 | 570 | #: altyo_settings.vala:1699 altyo_settings.vala:1710 altyo_settings.vala:1755 571 | #, c-format 572 | msgid "" 573 | "New value of %s will not be saved!\n" 574 | "%s" 575 | msgstr "" 576 | -------------------------------------------------------------------------------- /vapi/config.vapi: -------------------------------------------------------------------------------- 1 | public const string GETTEXT_PACKAGE; 2 | public const string DATA_DIRECTORY; 3 | public const string LOCALEDIR; 4 | public const string AY_GIT_HASH; 5 | public const string AY_CHANGELOG_TAG; 6 | -------------------------------------------------------------------------------- /vapi/vte-2.90.deps: -------------------------------------------------------------------------------- 1 | atk 2 | gdk-3.0 3 | gdk-pixbuf-2.0 4 | gtk+-3.0 5 | gio-2.0 6 | pango 7 | -------------------------------------------------------------------------------- /vapi/vte-2.90.vapi: -------------------------------------------------------------------------------- 1 | /* vte-2.90.vapi generated by vapigen, do not modify. */ 2 | 3 | [CCode (cprefix = "Vte", gir_namespace = "Vte", gir_version = "2.90", lower_case_cprefix = "vte_")] 4 | namespace Vte { 5 | [CCode (cheader_filename = "vte/vte.h", type_id = "vte_pty_get_type ()")] 6 | public class Pty : GLib.Object, GLib.Initable { 7 | [CCode (has_construct_function = false)] 8 | public Pty (Vte.PtyFlags flags) throws GLib.Error; 9 | public void child_setup (); 10 | public void close (); 11 | public static GLib.Quark error_quark (); 12 | [CCode (has_construct_function = false)] 13 | public Pty.foreign (int fd) throws GLib.Error; 14 | public int get_fd (); 15 | public bool get_size (out int rows, out int columns) throws GLib.Error; 16 | public bool set_size (int rows, int columns) throws GLib.Error; 17 | public void set_term (string? emulation); 18 | public bool set_utf8 (bool utf8) throws GLib.Error; 19 | public int fd { get; construct; } 20 | [NoAccessorMethod] 21 | public Vte.PtyFlags flags { get; construct; } 22 | [NoAccessorMethod] 23 | public string term { owned get; set; } 24 | } 25 | [CCode (cheader_filename = "vte/vte.h", type_id = "vte_terminal_get_type ()")] 26 | public class Terminal : Gtk.Widget, Atk.Implementor, Gtk.Buildable, Gtk.Scrollable { 27 | [CCode (has_construct_function = false, type = "GtkWidget*")] 28 | public Terminal (); 29 | public void copy_primary (); 30 | public void feed (string data, long length); 31 | public void feed_child (string text, long length); 32 | public void feed_child_binary (string data, long length); 33 | public bool fork_command_full (Vte.PtyFlags pty_flags, string? working_directory, [CCode (array_length = false, array_null_terminated = true)] string[] argv, [CCode (array_length = false, array_null_terminated = true)] string[]? envv, GLib.SpawnFlags spawn_flags, [CCode (delegate_target_pos = 6.5)] GLib.SpawnChildSetupFunc? child_setup, out GLib.Pid child_pid) throws GLib.Error; 34 | public bool get_allow_bold (); 35 | public bool get_audible_bell (); 36 | public long get_char_height (); 37 | public long get_char_width (); 38 | public int get_child_exit_status (); 39 | public long get_column_count (); 40 | public unowned string get_current_directory_uri (); 41 | public unowned string get_current_file_uri (); 42 | public Vte.TerminalCursorBlinkMode get_cursor_blink_mode (); 43 | public void get_cursor_position (out long column, out long row); 44 | public Vte.TerminalCursorShape get_cursor_shape (); 45 | public unowned string get_default_emulation (); 46 | public unowned string get_emulation (); 47 | public unowned string get_encoding (); 48 | public unowned Pango.FontDescription get_font (); 49 | public bool get_has_selection (); 50 | public unowned string get_icon_title (); 51 | public bool get_mouse_autohide (); 52 | public unowned Vte.Pty get_pty_object (); 53 | public long get_row_count (); 54 | public unowned string get_status_line (); 55 | public unowned string get_text (Vte.SelectionFunc is_selected, GLib.Array attributes); 56 | public unowned string get_text_include_trailing_spaces (Vte.SelectionFunc is_selected, GLib.Array attributes); 57 | public unowned string get_text_range (long start_row, long start_col, long end_row, long end_col, Vte.SelectionFunc is_selected, GLib.Array attributes); 58 | public bool get_visible_bell (); 59 | public unowned string get_window_title (); 60 | public void im_append_menuitems (Gtk.MenuShell menushell); 61 | public bool is_word_char (unichar c); 62 | public int match_add_gregex (GLib.Regex regex, GLib.RegexMatchFlags flags); 63 | public string? match_check (long column, long row, out int tag); 64 | public void match_clear_all (); 65 | public void match_remove (int tag); 66 | public void match_set_cursor (int tag, Gdk.Cursor? cursor); 67 | public void match_set_cursor_name (int tag, string cursor_name); 68 | public void match_set_cursor_type (int tag, Gdk.CursorType cursor_type); 69 | public void paste_primary (); 70 | public Vte.Pty pty_new (Vte.PtyFlags flags) throws GLib.Error; 71 | public void reset (bool clear_tabstops, bool clear_history); 72 | public bool search_find_next (); 73 | public bool search_find_previous (); 74 | public unowned GLib.Regex search_get_gregex (); 75 | public bool search_get_wrap_around (); 76 | public void search_set_gregex (GLib.Regex? regex); 77 | public void search_set_wrap_around (bool wrap_around); 78 | public void select_all (); 79 | public void select_none (); 80 | public void set_allow_bold (bool allow_bold); 81 | public void set_audible_bell (bool is_audible); 82 | public void set_background_image (Gdk.Pixbuf? image); 83 | public void set_background_image_file (string path); 84 | public void set_background_saturation (double saturation); 85 | public void set_background_tint_color (Gdk.Color color); 86 | public void set_background_transparent (bool transparent); 87 | public void set_backspace_binding (Vte.TerminalEraseBinding binding); 88 | public void set_color_background (Gdk.Color background); 89 | public void set_color_background_rgba (Gdk.RGBA background); 90 | public void set_color_bold (Gdk.Color bold); 91 | public void set_color_bold_rgba (Gdk.RGBA? bold); 92 | public void set_color_cursor (Gdk.Color? cursor_background); 93 | public void set_color_cursor_rgba (Gdk.RGBA? cursor_background); 94 | public void set_color_dim (Gdk.Color dim); 95 | public void set_color_dim_rgba (Gdk.RGBA? dim); 96 | public void set_color_foreground (Gdk.Color foreground); 97 | public void set_color_foreground_rgba (Gdk.RGBA foreground); 98 | public void set_color_highlight (Gdk.Color? highlight_background); 99 | public void set_color_highlight_rgba (Gdk.RGBA? highlight_background); 100 | public void set_colors (Gdk.Color? foreground, Gdk.Color? background, [CCode (array_length_cname = "palette_size", array_length_pos = 3.1, array_length_type = "glong")] Gdk.Color[] palette); 101 | public void set_colors_rgba (Gdk.RGBA? foreground, Gdk.RGBA? background, [CCode (array_length_cname = "palette_size", array_length_pos = 3.1, array_length_type = "gsize")] Gdk.RGBA[] palette); 102 | public void set_cursor_blink_mode (Vte.TerminalCursorBlinkMode mode); 103 | public void set_cursor_shape (Vte.TerminalCursorShape shape); 104 | public void set_default_colors (); 105 | public void set_delete_binding (Vte.TerminalEraseBinding binding); 106 | public void set_emulation (string? emulation); 107 | public void set_encoding (string? codeset); 108 | public void set_font (Pango.FontDescription? font_desc); 109 | public void set_font_from_string (string name); 110 | public void set_mouse_autohide (bool setting); 111 | public void set_opacity (uint16 opacity); 112 | public void set_pty_object (Vte.Pty? pty); 113 | public void set_scroll_background (bool scroll); 114 | public void set_scroll_on_keystroke (bool scroll); 115 | public void set_scroll_on_output (bool scroll); 116 | #if ALTERNATE_SCREEN_SCROLL 117 | public void set_alternate_screen_scroll (bool scroll); 118 | #endif 119 | public void set_scrollback_lines (long lines); 120 | public void set_size (long columns, long rows); 121 | public void set_visible_bell (bool is_visible); 122 | public void set_word_chars (string spec); 123 | public void watch_child (GLib.Pid child_pid); 124 | public bool write_contents (GLib.OutputStream stream, Vte.TerminalWriteFlags flags, GLib.Cancellable? cancellable = null) throws GLib.Error; 125 | public bool allow_bold { get; set; } 126 | public bool audible_bell { get; set; } 127 | [NoAccessorMethod] 128 | public string background_image_file { owned get; set; } 129 | [NoAccessorMethod] 130 | public Gdk.Pixbuf background_image_pixbuf { owned get; set; } 131 | [NoAccessorMethod] 132 | public double background_opacity { get; set; } 133 | [NoAccessorMethod] 134 | public double background_saturation { get; set; } 135 | [NoAccessorMethod] 136 | public Gdk.Color background_tint_color { get; set; } 137 | [NoAccessorMethod] 138 | public bool background_transparent { get; set; } 139 | [NoAccessorMethod] 140 | public Vte.TerminalEraseBinding backspace_binding { get; set; } 141 | public string current_directory_uri { get; } 142 | public string current_file_uri { get; } 143 | public Vte.TerminalCursorBlinkMode cursor_blink_mode { get; set; } 144 | public Vte.TerminalCursorShape cursor_shape { get; set; } 145 | [NoAccessorMethod] 146 | public Vte.TerminalEraseBinding delete_binding { get; set; } 147 | public string emulation { get; set; } 148 | public string encoding { get; set; } 149 | [NoAccessorMethod] 150 | public Pango.FontDescription font_desc { owned get; set; } 151 | public string icon_title { get; } 152 | [NoAccessorMethod] 153 | public bool pointer_autohide { get; set; } 154 | public Vte.Pty pty_object { get; set; } 155 | [NoAccessorMethod] 156 | public bool scroll_background { get; set; } 157 | [NoAccessorMethod] 158 | public bool scroll_on_keystroke { get; set; } 159 | [NoAccessorMethod] 160 | public bool scroll_on_output { get; set; } 161 | [NoAccessorMethod] 162 | public uint scrollback_lines { get; set; } 163 | public bool visible_bell { get; set; } 164 | public string window_title { get; } 165 | [NoAccessorMethod] 166 | public string word_chars { owned get; set; } 167 | public virtual signal void beep (); 168 | public virtual signal void char_size_changed (uint char_width, uint char_height); 169 | public virtual signal void child_exited (); 170 | public virtual signal void commit (string text, uint size); 171 | public virtual signal void contents_changed (); 172 | [HasEmitter] 173 | public virtual signal void copy_clipboard (); 174 | public signal void current_directory_uri_changed (); 175 | public signal void current_file_uri_changed (); 176 | public virtual signal void cursor_moved (); 177 | public virtual signal void decrease_font_size (); 178 | public virtual signal void deiconify_window (); 179 | public virtual signal void emulation_changed (); 180 | public virtual signal void encoding_changed (); 181 | public virtual signal void eof (); 182 | public virtual signal void icon_title_changed (); 183 | public virtual signal void iconify_window (); 184 | public virtual signal void increase_font_size (); 185 | public virtual signal void lower_window (); 186 | public virtual signal void maximize_window (); 187 | public virtual signal void move_window (uint x, uint y); 188 | [HasEmitter] 189 | public virtual signal void paste_clipboard (); 190 | public virtual signal void raise_window (); 191 | public virtual signal void refresh_window (); 192 | public virtual signal void resize_window (uint width, uint height); 193 | public virtual signal void restore_window (); 194 | public virtual signal void selection_changed (); 195 | public virtual signal void status_line_changed (); 196 | public virtual signal void text_deleted (); 197 | public virtual signal void text_inserted (); 198 | public virtual signal void text_modified (); 199 | public virtual signal void text_scrolled (int delta); 200 | public virtual signal void window_title_changed (); 201 | } 202 | [CCode (cheader_filename = "vte/vte.h", cname = "_VteCharAttributes", has_type_id = false)] 203 | public struct _CharAttributes { 204 | } 205 | [CCode (cheader_filename = "vte/vte.h", cprefix = "VTE_PTY_", type_id = "vte_pty_flags_get_type ()")] 206 | [Flags] 207 | public enum PtyFlags { 208 | NO_LASTLOG, 209 | NO_UTMP, 210 | NO_WTMP, 211 | NO_HELPER, 212 | NO_FALLBACK, 213 | DEFAULT 214 | } 215 | [CCode (cheader_filename = "vte/vte.h", cprefix = "VTE_ANTI_ALIAS_", type_id = "vte_terminal_anti_alias_get_type ()")] 216 | public enum TerminalAntiAlias { 217 | USE_DEFAULT, 218 | FORCE_ENABLE, 219 | FORCE_DISABLE 220 | } 221 | [CCode (cheader_filename = "vte/vte.h", cprefix = "VTE_CURSOR_BLINK_", type_id = "vte_terminal_cursor_blink_mode_get_type ()")] 222 | public enum TerminalCursorBlinkMode { 223 | SYSTEM, 224 | ON, 225 | OFF 226 | } 227 | [CCode (cheader_filename = "vte/vte.h", cprefix = "VTE_CURSOR_SHAPE_", type_id = "vte_terminal_cursor_shape_get_type ()")] 228 | public enum TerminalCursorShape { 229 | BLOCK, 230 | IBEAM, 231 | UNDERLINE 232 | } 233 | [CCode (cheader_filename = "vte/vte.h", cprefix = "VTE_ERASE_", type_id = "vte_terminal_erase_binding_get_type ()")] 234 | public enum TerminalEraseBinding { 235 | AUTO, 236 | ASCII_BACKSPACE, 237 | ASCII_DELETE, 238 | DELETE_SEQUENCE, 239 | TTY 240 | } 241 | [CCode (cheader_filename = "vte/vte.h", cprefix = "VTE_TERMINAL_WRITE_", type_id = "vte_terminal_write_flags_get_type ()")] 242 | public enum TerminalWriteFlags { 243 | DEFAULT 244 | } 245 | [CCode (cheader_filename = "vte/vte.h", cprefix = "VTE_PTY_ERROR_")] 246 | public errordomain PtyError { 247 | PTY_HELPER_FAILED, 248 | PTY98_FAILED; 249 | public static GLib.Quark quark (); 250 | } 251 | [CCode (cheader_filename = "vte/vte.h", instance_pos = 3.9)] 252 | public delegate bool SelectionFunc (Vte.Terminal terminal, long column, long row); 253 | [CCode (cheader_filename = "vte/vte.h")] 254 | public const int MAJOR_VERSION; 255 | [CCode (cheader_filename = "vte/vte.h")] 256 | public const int MICRO_VERSION; 257 | [CCode (cheader_filename = "vte/vte.h")] 258 | public const int MINOR_VERSION; 259 | [CCode (cheader_filename = "vte/vte.h")] 260 | public static string? get_user_shell (); 261 | } 262 | -------------------------------------------------------------------------------- /vapi/xkb.vapi: -------------------------------------------------------------------------------- 1 | using X; 2 | 3 | [CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "X11/XKBlib.h")] 4 | namespace Xkb { 5 | [CCode (cname = "XkbGetState")] 6 | public void get_state (X.Display dpy, uint device_spec, out State state); 7 | 8 | [CCode (cname = "XkbLockGroup")] 9 | public void lock_group (X.Display dpy, uint device_spec, uint group); 10 | 11 | [Compact] 12 | [CCode (cname = "XkbStateRec", free_function = "")] 13 | public struct State { 14 | uchar group; 15 | uchar locked_group; 16 | ushort base_group; 17 | ushort latched_group; 18 | uchar mods; 19 | uchar base_mods; 20 | uchar latched_mods; 21 | uchar locked_mods; 22 | uchar compat_state; 23 | uchar grab_mods; 24 | uchar compat_grab_mods; 25 | uchar lookup_mods; 26 | uchar compat_lookup_mods; 27 | ushort ptr_buttons; 28 | } 29 | 30 | [CCode (cname = "XkbUseCoreKbd")] 31 | public int UseCoreKbd; 32 | 33 | } 34 | --------------------------------------------------------------------------------