mirror of
https://github.com/linuxmint/timeshift.git
synced 2024-09-11 08:55:25 +03:00
Merge branch 'master' into patch-7
This commit is contained in:
commit
3f97457ca6
17
.bzrignore
17
.bzrignore
@ -1,17 +0,0 @@
|
||||
src/timeshift
|
||||
src/timeshift-gtk
|
||||
designs/
|
||||
release/source
|
||||
release/amd64
|
||||
release/i386
|
||||
release/armel
|
||||
release/armhf
|
||||
release/*.deb
|
||||
release/*.run
|
||||
*.geany
|
||||
*.mo
|
||||
*.c
|
||||
*.o
|
||||
.git
|
||||
.bzr
|
||||
*~
|
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -7,7 +7,9 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Note:** This application is provided "as-is" without support or warranty. If you need help with issues, consider [making a donation](https://www.paypal.com/cgi-bin/webscr?business=teejeetech@gmail.com&cmd=_xclick¤cy_code=USD&item_name=Timeshift+Donation) to support the development.
|
||||
**Note:** This application is provided "as-is" without support or warranty. The purpose of this tracker is to keep track of issues. It is checked once a year when the app is being updated. If you face any issue you can report it here but please keep in mind that there is no dedicated support. The issue will be investigated and fixed during the next update which may occur many months after you report the issue.
|
||||
|
||||
**Note:** If you are a Linux Mint user and you need help with an issue, consider posting the issue on [Linux Mint forums](https://forums.linuxmint.com) where there are more people to help you out.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -7,7 +7,7 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Note:** This application is provided "as-is" without support or warranty. If you have any requests, consider [making a donation](https://www.paypal.com/cgi-bin/webscr?business=teejeetech@gmail.com&cmd=_xclick¤cy_code=USD&item_name=Timeshift+Donation) to support the development.
|
||||
**Note:** This application is provided "as-is" without support or warranty. If you need changes or additional features in the application, please download the source code, make the changes, test it properly, and then submit a pull request. The changes will be reviewed and merged in the next update.
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -23,3 +23,7 @@ snap/
|
||||
release/
|
||||
debian/timeshift/
|
||||
rpm/
|
||||
debian/debhelper-build-stamp
|
||||
debian/files
|
||||
debian/timeshift.debhelper.log
|
||||
debian/timeshift.substvars
|
||||
|
2
AUTHORS
2
AUTHORS
@ -1,3 +1,3 @@
|
||||
|
||||
Copyright (C) 2013 Tony George (teejee2008@gmail.com)
|
||||
Copyright (C) 2020 Tony George (teejeetech@gmail.com)
|
||||
|
||||
|
14
BUILD_CONFIG
14
BUILD_CONFIG
@ -2,5 +2,19 @@
|
||||
app_fullname="Timeshift"
|
||||
app_name="timeshift"
|
||||
pkg_name="timeshift"
|
||||
|
||||
pkg_version=$(dpkg-parsechangelog --show-field Version)
|
||||
|
||||
build_deb=1
|
||||
build_rpm=0
|
||||
build_arch=0
|
||||
|
||||
deb_arch="amd64 i386 arm64 armhf" # amd64 i386 arm64 armhf
|
||||
rpm_arch="" # x86_64 i686
|
||||
arch_arch="" # x86_64 i686
|
||||
|
||||
pkg_version=$(dpkg-parsechangelog --show-field Version)
|
||||
|
||||
git_origin="git@github.com:teejee2008/timeshift.git"
|
||||
|
||||
|
||||
|
16
README.md
16
README.md
@ -164,6 +164,12 @@ If the backup device is running out of space, try the following steps:
|
||||
* EFI systems are fully supported. Ensure that the ***/boot/efi*** partition is mapped while restoring a snapshot. It will be mapped automatically if detected.
|
||||
* If you are restoring from Live CD/USB, and your installed system uses EFI mode, then you must boot from Live CD/USB in EFI mode.
|
||||
|
||||
## Support
|
||||
|
||||
If you use Linux Mint and need support for an issue please use the [Linux Mint support forums](https://forums.linuxmint.com)
|
||||
|
||||
Issues reported on the Issue Tracker will be fixed during the next update. Please do not expect a response as the tracker is checked once a year when the app is being updated.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This program is free for personal and commercial use and comes with absolutely no warranty. You use this program entirely at your own risk. The author will not be liable for any damages arising from the use of this program. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
@ -175,20 +181,16 @@ You can contribute to this project in various ways:
|
||||
- Submitting ideas, and reporting issues in the [tracker](https://github.com/teejee2008/timeshift/issues)
|
||||
- Translating this application to other languages
|
||||
- Contributing code changes by fixing issues and submitting a pull request
|
||||
- Making a donation via PayPal or bitcoin, or signing-up as a patron on Patreon
|
||||
- Making a donation via PayPal or bitcoin
|
||||
|
||||
## Donate
|
||||
|
||||
*Timeshift* is a non-commercial application. I work on it during my free time based on my requirements and interest. If you wish to support this project, you can make a donation for $10 or more via PayPal. Your contributions will help keep the project alive and support future development.
|
||||
*Timeshift* is a non-commercial application. I work on it during my free time based on my requirements and interest. If you wish to support this project, you can make a donation for $10 or more via PayPal. Your contributions will help keep the project alive.
|
||||
|
||||
**PayPal** ~ If you find this application useful and wish to say thanks, you can buy me a coffee by making a donation with Paypal.
|
||||
**PayPal**
|
||||
|
||||
[![](images/PayPal.png)](https://www.paypal.com/cgi-bin/webscr?business=teejeetech@gmail.com&cmd=_xclick¤cy_code=USD&amount=10&item_name=Timeshift%20Donation)
|
||||
|
||||
**Patreon** ~ You can also sign up as a sponsor on [Patreon.com](https://www.patreon.com/teejeetech). As a patron you will get access to beta releases of new applications that I'm working on. You will also get news and updates about new features that are not published elsewhere.
|
||||
|
||||
[![](images/patreon.png)](https://www.patreon.com/bePatron?u=3059450)
|
||||
|
||||
**Bitcoin** ~ You can send bitcoins at this address or by scanning the QR code below:
|
||||
|
||||
```1KdEyJjkuEW8aZWjenf4x5uEeHo9VTYqio```
|
||||
|
66
build-deb.sh
66
build-deb.sh
@ -1,66 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for prog in pbuilder-dist make dpkg-source ; do
|
||||
if sh -c "which $prog 2> /dev/null"; then true ; else echo "You don\'t have $prog, install it" ; exit ; fi
|
||||
done
|
||||
|
||||
backup=`pwd`
|
||||
DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
cd $DIR
|
||||
|
||||
. ./BUILD_CONFIG
|
||||
|
||||
sh build-source.sh
|
||||
|
||||
rm -fv release/${pkg_name}-*.deb
|
||||
|
||||
build_deb_for_dist() {
|
||||
|
||||
dist=$1
|
||||
arch=$2
|
||||
|
||||
echo ""
|
||||
echo "=========================================================================="
|
||||
echo " build-deb.sh : $dist-$arch"
|
||||
echo "=========================================================================="
|
||||
echo ""
|
||||
|
||||
rm -rfv release/${arch}
|
||||
mkdir -pv release/${arch}
|
||||
|
||||
echo "-------------------------------------------------------------------------"
|
||||
|
||||
pbuilder-dist $dist $arch build release/source/${pkg_name}*.dsc --buildresult release/$arch
|
||||
|
||||
if [ $? -ne 0 ]; then cd "$backup"; echo "Failed"; exit 1; fi
|
||||
|
||||
echo "--------------------------------------------------------------------------"
|
||||
|
||||
cp -pv --no-preserve=ownership release/${arch}/${pkg_name}*.deb release/${pkg_name}-v${pkg_version}-${arch}.deb
|
||||
|
||||
if [ $? -ne 0 ]; then cd "$backup"; echo "Failed"; exit 1; fi
|
||||
|
||||
echo "--------------------------------------------------------------------------"
|
||||
|
||||
}
|
||||
|
||||
arches=""
|
||||
if [ -z $1 ]; then
|
||||
arches="i386 amd64"
|
||||
else
|
||||
arches="$1"
|
||||
fi
|
||||
|
||||
for arch in $arches
|
||||
do
|
||||
|
||||
build_deb_for_dist xenial $arch
|
||||
|
||||
done
|
||||
|
||||
#build_deb_for_dist xenial i386
|
||||
#build_deb_for_dist xenial amd64
|
||||
#build_deb_for_dist stretch armel
|
||||
#build_deb_for_dist stretch armhf
|
||||
|
||||
cd "$backup"
|
@ -1,60 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for prog in pbuilder-dist make dpkg-source ; do
|
||||
if sh -c "which $prog 2> /dev/null" ; then true ; else echo "You don\'t have $prog, install it" ; exit ; fi
|
||||
done
|
||||
|
||||
backup=`pwd`
|
||||
DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
cd $DIR
|
||||
|
||||
. ./BUILD_CONFIG
|
||||
|
||||
rm -vf release/*.run
|
||||
rm -vf release/*.deb
|
||||
|
||||
arches=""
|
||||
if [ -z $1 ]; then
|
||||
arches="i386 amd64"
|
||||
# build deb
|
||||
sh build-deb.sh
|
||||
else
|
||||
arches="$1"
|
||||
# build deb
|
||||
sh build-deb.sh "$1"
|
||||
fi
|
||||
|
||||
for arch in $arches
|
||||
do
|
||||
|
||||
rm -rfv release/${arch}/files
|
||||
mkdir -pv release/${arch}/files
|
||||
|
||||
echo ""
|
||||
echo "=========================================================================="
|
||||
echo " build-installers.sh : $arch"
|
||||
echo "=========================================================================="
|
||||
echo ""
|
||||
|
||||
dpkg-deb -x release/${pkg_name}-v${pkg_version}-${arch}.deb release/${arch}/files
|
||||
|
||||
if [ $? -ne 0 ]; then cd "$backup"; echo "Failed"; exit 1;fi
|
||||
|
||||
echo "--------------------------------------------------------------------------"
|
||||
|
||||
rm -rfv release/${arch}/${pkg_name}*.* # remove source files created by pbuilder
|
||||
cp -pv --no-preserve=ownership release/sanity.config release/${arch}/sanity.config
|
||||
sanity --generate --base-path release/${arch} --out-path release --arch ${arch} --xz
|
||||
|
||||
if [ $? -ne 0 ]; then cd "$backup"; echo "Failed"; exit 1; fi
|
||||
|
||||
mv -v release/*${arch}.run release/${pkg_name}-v${pkg_version}-${arch}.run
|
||||
|
||||
echo "--------------------------------------------------------------------------"
|
||||
|
||||
done
|
||||
|
||||
cp -vf release/*.run ../PACKAGES/
|
||||
cp -vf release/*.deb ../PACKAGES/
|
||||
|
||||
cd "$backup"
|
@ -1,50 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
for prog in pbuilder-dist make dpkg-source ; do
|
||||
if sh -c "which $prog 2> /dev/null"; then true ; else echo "You don\'t have $prog, install it" ; exit ; fi
|
||||
done
|
||||
|
||||
backup=`pwd`
|
||||
DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
cd "$DIR"
|
||||
|
||||
. ./BUILD_CONFIG
|
||||
|
||||
echo ""
|
||||
echo "=========================================================================="
|
||||
echo " build-source.sh"
|
||||
echo "=========================================================================="
|
||||
echo ""
|
||||
|
||||
echo "app_name: $app_name"
|
||||
echo "pkg_name: $pkg_name"
|
||||
echo "--------------------------------------------------------------------------"
|
||||
|
||||
# clean build dir
|
||||
|
||||
rm -rfv /tmp/builds
|
||||
mkdir -pv /tmp/builds
|
||||
|
||||
make clean
|
||||
|
||||
rm -rfv release/source
|
||||
mkdir -pv release/source
|
||||
|
||||
echo "--------------------------------------------------------------------------"
|
||||
|
||||
# build source package
|
||||
dpkg-source --build ./
|
||||
|
||||
mv -vf ../$pkg_name*.dsc release/source/
|
||||
mv -vf ../$pkg_name*.tar.xz release/source/
|
||||
|
||||
if [ $? -ne 0 ]; then cd "$backup"; echo "Failed"; exit 1; fi
|
||||
|
||||
echo "--------------------------------------------------------------------------"
|
||||
|
||||
# list files
|
||||
ls -l release/source
|
||||
|
||||
echo "-------------------------------------------------------------------------"
|
||||
|
||||
cd "$backup"
|
27
debian/changelog
vendored
27
debian/changelog
vendored
@ -1,3 +1,30 @@
|
||||
timeshift (20.11.1) focal; urgency=medium
|
||||
|
||||
* Fix #631: Escape single quote in LUKS password when unlocking device
|
||||
|
||||
* Fix #626: Filters: Save filter order changes when clicking OK
|
||||
|
||||
* Fix #643: Filters: Save changes after Include/Exclude radio is toggled
|
||||
|
||||
* Fix #668: Filters: Save changes immediately after pattern is edited
|
||||
|
||||
* Fix #666: Filters: Save changes immediately after adding a pattern;
|
||||
and before clicking Summary button
|
||||
|
||||
* Move config file to /etc/timeshift/timeshift.json
|
||||
|
||||
* Move default config to /etc/timeshift/default.json
|
||||
|
||||
* AppStream: Install only under /usr/share/metainfo. Don't install
|
||||
under /usr/share/appdata/
|
||||
|
||||
* Remove unused functions and code
|
||||
|
||||
* pkexec: Don't pass DISPLAY and AUTHORITY in launcher script
|
||||
|
||||
-- Tony George <teejeetech@gmail.com> Sun, 15 Nov 2020 20:00:00 +0530
|
||||
|
||||
|
||||
timeshift (20.03) xenial; urgency=medium
|
||||
|
||||
* Fix an issue with script execution
|
||||
|
6
makefile
6
makefile
@ -13,6 +13,12 @@ pot:
|
||||
manpage:
|
||||
cd src; make manpage
|
||||
|
||||
dist-release:
|
||||
build
|
||||
|
||||
dist-deb:
|
||||
build-deb amd64
|
||||
|
||||
clean:
|
||||
cd src; make clean
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -38,7 +38,7 @@ using TeeJee.Misc;
|
||||
public Main App;
|
||||
public const string AppName = "Timeshift";
|
||||
public const string AppShortName = "timeshift";
|
||||
public const string AppVersion = "20.03";
|
||||
public const string AppVersion = "20.11.1";
|
||||
public const string AppAuthor = "Tony George";
|
||||
public const string AppAuthorEmail = "teejeetech@gmail.com";
|
||||
|
||||
|
@ -42,6 +42,7 @@ public class Main : GLib.Object{
|
||||
public string share_folder = "";
|
||||
public string rsnapshot_conf_path = "";
|
||||
public string app_conf_path = "";
|
||||
public string app_conf_path_old = "";
|
||||
public string app_conf_path_default = "";
|
||||
public bool first_run = false;
|
||||
|
||||
@ -270,8 +271,9 @@ public class Main : GLib.Object{
|
||||
|
||||
this.app_path = (File.new_for_path (args[0])).get_parent().get_path ();
|
||||
this.share_folder = "/usr/share";
|
||||
this.app_conf_path = "/etc/timeshift.json";
|
||||
this.app_conf_path_default = "/etc/default/timeshift.json";
|
||||
this.app_conf_path = "/etc/timeshift/timeshift.json";
|
||||
this.app_conf_path_old = "/etc/timeshift.json";
|
||||
this.app_conf_path_default = "/etc/timeshift/default.json";
|
||||
//sys_root and sys_home will be initalized by update_partition_list()
|
||||
|
||||
// check if running locally ------------------------
|
||||
@ -3104,12 +3106,17 @@ public class Main : GLib.Object{
|
||||
// check if first run -----------------------
|
||||
|
||||
var f = File.new_for_path(this.app_conf_path);
|
||||
|
||||
if (!f.query_exists()) {
|
||||
|
||||
if (file_exists(app_conf_path_old)){
|
||||
// move old file
|
||||
file_move(app_conf_path_old, app_conf_path);
|
||||
}
|
||||
else if (file_exists(app_conf_path_default)){
|
||||
// copy default file
|
||||
file_copy(app_conf_path_default, app_conf_path);
|
||||
}
|
||||
if (!f.query_exists()) {
|
||||
set_first_run_flag();
|
||||
return;
|
||||
}
|
||||
|
||||
// load settings from config file --------------------------
|
||||
@ -3125,12 +3132,12 @@ public class Main : GLib.Object{
|
||||
|
||||
bool do_first_run = json_get_bool(config, "do_first_run", false); // false as default
|
||||
|
||||
btrfs_mode = json_get_bool(config, "btrfs_mode", false); // false as default
|
||||
|
||||
if (do_first_run){
|
||||
set_first_run_flag();
|
||||
}
|
||||
|
||||
btrfs_mode = json_get_bool(config, "btrfs_mode", false); // false as default
|
||||
|
||||
if (config.has_member("include_btrfs_home")){
|
||||
include_btrfs_home_for_backup = json_get_bool(config, "include_btrfs_home", include_btrfs_home_for_backup);
|
||||
}
|
||||
@ -3170,6 +3177,7 @@ public class Main : GLib.Object{
|
||||
exclude_list_user.clear();
|
||||
|
||||
if (config.has_member ("exclude")){
|
||||
|
||||
foreach (Json.Node jnode in config.get_array_member ("exclude").get_elements()) {
|
||||
|
||||
string path = jnode.get_string();
|
||||
@ -3186,7 +3194,9 @@ public class Main : GLib.Object{
|
||||
exclude_app_names.clear();
|
||||
|
||||
if (config.has_member ("exclude-apps")){
|
||||
|
||||
var apps = config.get_array_member("exclude-apps");
|
||||
|
||||
foreach (Json.Node jnode in apps.get_elements()) {
|
||||
|
||||
string name = jnode.get_string();
|
||||
|
@ -26,7 +26,6 @@ using Gtk;
|
||||
using Gee;
|
||||
using Json;
|
||||
|
||||
|
||||
using TeeJee.Logging;
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.JsonHelper;
|
||||
@ -38,7 +37,7 @@ using TeeJee.Misc;
|
||||
public Main App;
|
||||
public const string AppName = "Timeshift";
|
||||
public const string AppShortName = "timeshift";
|
||||
public const string AppVersion = "20.03";
|
||||
public const string AppVersion = "20.11.1";
|
||||
public const string AppAuthor = "Tony George";
|
||||
public const string AppAuthorEmail = "teejeetech@gmail.com";
|
||||
|
||||
@ -72,6 +71,7 @@ public class AppGtk : GLib.Object {
|
||||
}
|
||||
|
||||
private static void set_locale() {
|
||||
|
||||
log_debug("setting locale...");
|
||||
Intl.setlocale(GLib.LocaleCategory.MESSAGES, "timeshift");
|
||||
Intl.textdomain(GETTEXT_PACKAGE);
|
||||
@ -107,6 +107,7 @@ public class AppGtk : GLib.Object {
|
||||
}
|
||||
|
||||
public static string help_message() {
|
||||
|
||||
string msg = "\n%s v%s by Tony George (%s)\n".printf(AppName, AppVersion, AppAuthorEmail);
|
||||
msg += "\n";
|
||||
msg += _("Syntax") + ": timeshift-gtk [options]\n";
|
||||
@ -123,6 +124,7 @@ public class AppGtk : GLib.Object {
|
||||
public static void check_if_admin(){
|
||||
|
||||
if (!user_is_admin()){
|
||||
|
||||
var msg = _("Admin access is required to backup and restore system files.") + "\n";
|
||||
msg += _("Please re-run the application as admin (using 'sudo' or 'su')");
|
||||
|
||||
|
@ -121,6 +121,8 @@ class ExcludeBox : Gtk.Box{
|
||||
}
|
||||
|
||||
treeview_update_item(ref iter, pattern);
|
||||
|
||||
save_changes();
|
||||
});
|
||||
|
||||
// column
|
||||
@ -155,6 +157,8 @@ class ExcludeBox : Gtk.Box{
|
||||
}
|
||||
|
||||
treeview_update_item(ref iter, pattern);
|
||||
|
||||
save_changes();
|
||||
});
|
||||
|
||||
// column
|
||||
@ -206,6 +210,8 @@ class ExcludeBox : Gtk.Box{
|
||||
}
|
||||
|
||||
model.set (iter, 0, pattern, -1);
|
||||
|
||||
save_changes();
|
||||
});
|
||||
}
|
||||
|
||||
@ -229,6 +235,8 @@ class ExcludeBox : Gtk.Box{
|
||||
treeview_add_item(treeview, pattern); // don't strip
|
||||
Main.first_snapshot_size = 0; //re-calculate
|
||||
}
|
||||
|
||||
save_changes();
|
||||
});
|
||||
|
||||
button = add_button(hbox, _("Add Files"), _("Add files"), size_group, null);
|
||||
@ -258,6 +266,7 @@ class ExcludeBox : Gtk.Box{
|
||||
|
||||
button = add_button(hbox, _("Summary"), "", size_group, null);
|
||||
button.clicked.connect(()=>{
|
||||
save_changes();
|
||||
new ExcludeListSummaryWindow(false);
|
||||
});
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ class MainWindow : Gtk.Window{
|
||||
|
||||
// scrolled
|
||||
var scrolled = new Gtk.ScrolledWindow(null, null);
|
||||
scrolled.set_shadow_type (ShadowType.ETCHED_IN);
|
||||
//scrolled.set_shadow_type (ShadowType.ETCHED_IN);
|
||||
//scrolled.margin = 6;
|
||||
//scrolled.margin_top = 0;
|
||||
scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
@ -298,7 +298,7 @@ class MainWindow : Gtk.Window{
|
||||
|
||||
// scrolled
|
||||
scrolled = new Gtk.ScrolledWindow(null, null);
|
||||
scrolled.set_shadow_type (ShadowType.ETCHED_IN);
|
||||
//scrolled.set_shadow_type (ShadowType.ETCHED_IN);
|
||||
scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
scrolled.vscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
scrolled.set_no_show_all(true);
|
||||
@ -334,7 +334,7 @@ class MainWindow : Gtk.Window{
|
||||
//vbox_free_space = vbox;
|
||||
|
||||
scrolled = new Gtk.ScrolledWindow(null, null);
|
||||
scrolled.set_shadow_type (ShadowType.ETCHED_IN);
|
||||
//scrolled.set_shadow_type (ShadowType.ETCHED_IN);
|
||||
scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
scrolled.vscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
scrolled.set_no_show_all(true);
|
||||
|
@ -126,6 +126,7 @@ class SettingsWindow : Gtk.Window{
|
||||
bbox.add(btn_ok);
|
||||
|
||||
btn_ok.clicked.connect(()=>{
|
||||
save_changes();
|
||||
this.destroy();
|
||||
});
|
||||
|
||||
|
@ -221,7 +221,7 @@ class SnapshotListBox : Gtk.Box{
|
||||
|
||||
//cell_desc
|
||||
col_desc = new TreeViewColumn();
|
||||
col_desc.title = _("Comments");
|
||||
col_desc.title = _("Comments (click to edit)");
|
||||
col_desc.resizable = true;
|
||||
col_desc.clickable = true;
|
||||
col_desc.expand = true;
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* ArchiveFile.vala
|
||||
*
|
||||
* Copyright 2012-2018 Tony George <teejeetech@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
using GLib;
|
||||
using Gtk;
|
||||
using Gee;
|
||||
using Json;
|
||||
|
||||
using TeeJee.Logging;
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.JsonHelper;
|
||||
using TeeJee.ProcessHelper;
|
||||
using TeeJee.GtkHelper;
|
||||
using TeeJee.System;
|
||||
using TeeJee.Misc;
|
||||
|
||||
public class ArchiveFile : FileItem {
|
||||
|
||||
// additional properties
|
||||
public int64 archive_size = 0;
|
||||
public int64 archive_unpacked_size = 0;
|
||||
public double compression_ratio = 0.0;
|
||||
public string archive_type = "";
|
||||
public string archive_method = "";
|
||||
public bool archive_is_encrypted = false;
|
||||
public bool archive_is_solid = false;
|
||||
public int archive_blocks = 0;
|
||||
public int64 archive_header_size = 0;
|
||||
public DateTime archive_modified;
|
||||
|
||||
public string password = "";
|
||||
public string keyfile = "";
|
||||
|
||||
// extraction
|
||||
public Gee.ArrayList<string> extract_list;
|
||||
|
||||
// temp
|
||||
public string temp_dir = "";
|
||||
public string script_file = "";
|
||||
public string log_file = "";
|
||||
|
||||
public ArchiveFile(string archive_file_path = "") {
|
||||
base.from_path_and_type(archive_file_path, FileType.REGULAR);
|
||||
is_archive = true;
|
||||
|
||||
//this.tag = this;
|
||||
|
||||
extract_list = new Gee.ArrayList<string>();
|
||||
temp_dir = TEMP_DIR + "/" + timestamp_for_path();
|
||||
log_file = temp_dir + "/log.txt";
|
||||
script_file = temp_dir + "/convert.sh";
|
||||
dir_create (temp_dir);
|
||||
}
|
||||
|
||||
public void add_items(Gee.ArrayList<string> item_list){
|
||||
if (item_list.size > 0){
|
||||
foreach(string item in item_list){
|
||||
add_child_from_disk(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
public signal void task_complete();
|
||||
|
||||
protected AsyncTask(){
|
||||
|
||||
working_dir = TEMP_DIR + "/" + timestamp_for_path();
|
||||
script_file = path_combine(working_dir, "script.sh");
|
||||
log_file = path_combine(working_dir, "task.log");
|
||||
@ -258,6 +259,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
protected abstract void parse_stderr_line(string err_line);
|
||||
|
||||
private void finish(){
|
||||
|
||||
// finish() gets called by 2 threads but should be executed only once
|
||||
if (finish_called) { return; }
|
||||
finish_called = true;
|
||||
@ -317,6 +319,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
protected abstract void finish_task();
|
||||
|
||||
protected int read_exit_code(){
|
||||
|
||||
exit_code = -1;
|
||||
var path = file_parent(script_file) + "/status";
|
||||
if (file_exists(path)){
|
||||
@ -328,12 +331,14 @@ public abstract class AsyncTask : GLib.Object{
|
||||
}
|
||||
|
||||
public bool is_running(){
|
||||
|
||||
return (status == AppStatus.RUNNING);
|
||||
}
|
||||
|
||||
// public actions --------------
|
||||
|
||||
public void pause() {
|
||||
|
||||
Pid sub_child_pid;
|
||||
foreach (long pid in get_process_children(child_pid)) {
|
||||
sub_child_pid = (Pid) pid;
|
||||
@ -344,6 +349,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
|
||||
Pid sub_child_pid;
|
||||
foreach (long pid in get_process_children(child_pid)) {
|
||||
sub_child_pid = (Pid) pid;
|
||||
@ -354,6 +360,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
}
|
||||
|
||||
public void stop(AppStatus status_to_update = AppStatus.CANCELLED) {
|
||||
|
||||
// we need to un-freeze the processes before we kill them
|
||||
if (status == AppStatus.PAUSED) {
|
||||
resume();
|
||||
@ -367,6 +374,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
}
|
||||
|
||||
public void set_priority() {
|
||||
|
||||
if (background_mode){
|
||||
set_priority_value(5);
|
||||
}
|
||||
@ -376,6 +384,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
}
|
||||
|
||||
public void set_priority_value(int prio) {
|
||||
|
||||
Pid app_pid = Posix.getpid();
|
||||
process_set_priority (app_pid, prio);
|
||||
|
||||
@ -414,6 +423,7 @@ public abstract class AsyncTask : GLib.Object{
|
||||
}
|
||||
|
||||
public void print_app_status(){
|
||||
|
||||
switch(status){
|
||||
case AppStatus.NOT_STARTED:
|
||||
log_debug("status=%s".printf("NOT_STARTED"));
|
||||
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Bash.vala
|
||||
*
|
||||
* Copyright 2012-2018 Tony George <teejeetech@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
using GLib;
|
||||
using Gtk;
|
||||
using Gee;
|
||||
using Json;
|
||||
|
||||
using TeeJee.Logging;
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.JsonHelper;
|
||||
using TeeJee.ProcessHelper;
|
||||
using TeeJee.GtkHelper;
|
||||
using TeeJee.System;
|
||||
using TeeJee.Misc;
|
||||
|
||||
public class Bash : AsyncTask {
|
||||
|
||||
public Pid bash_pid = -1;
|
||||
public int status_code = -1;
|
||||
private static Gee.HashMap<string, Regex> regex_list;
|
||||
|
||||
public Bash() {
|
||||
init_regular_expressions();
|
||||
}
|
||||
|
||||
private static void init_regular_expressions(){
|
||||
if (regex_list != null){
|
||||
return; // already initialized
|
||||
}
|
||||
|
||||
regex_list = new Gee.HashMap<string,Regex>();
|
||||
|
||||
try {
|
||||
//Example: status=-1
|
||||
regex_list["status"] = new Regex("""status=([0-9\-]+)""");
|
||||
}
|
||||
catch (Error e) {
|
||||
log_error (e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// execution ----------------------------
|
||||
|
||||
public void start_shell() {
|
||||
dir_create(working_dir);
|
||||
|
||||
var sh = "bash -c 'pkexec bash'";
|
||||
save_bash_script_temp(sh, script_file);
|
||||
begin();
|
||||
log_debug("Started bash shell");
|
||||
|
||||
if (status == AppStatus.RUNNING){
|
||||
bash_pid = -1;
|
||||
while ((status == AppStatus.RUNNING) && (bash_pid == -1)) {
|
||||
sleep(200);
|
||||
var children = get_process_children(child_pid);
|
||||
if (children.length > 0){
|
||||
bash_pid = children[0];
|
||||
}
|
||||
}
|
||||
|
||||
log_debug("script pid: %d".printf(child_pid));
|
||||
log_debug("bash shell pid: %d".printf(bash_pid));
|
||||
}
|
||||
}
|
||||
|
||||
public override void parse_stdout_line(string out_line){
|
||||
if ((out_line == null) || (out_line.length == 0)) {
|
||||
return;
|
||||
}
|
||||
MatchInfo match;
|
||||
if (regex_list["status"].match(out_line, 0, out match)) {
|
||||
status_code = int.parse(match.fetch(1));
|
||||
}
|
||||
stdout.printf(out_line + "\n");
|
||||
stdout.flush();
|
||||
}
|
||||
|
||||
public override void parse_stderr_line(string err_line){
|
||||
stdout.printf(err_line + "\n");
|
||||
stdout.flush();
|
||||
}
|
||||
|
||||
public int execute(string line){
|
||||
status_code = -1;
|
||||
write_stdin(line);
|
||||
write_stdin("echo status=$?");
|
||||
|
||||
while (status_code == -1){
|
||||
sleep(200);
|
||||
gtk_do_events();
|
||||
}
|
||||
|
||||
return status_code;
|
||||
}
|
||||
|
||||
protected override void finish_task(){
|
||||
log_debug("Bash: finish_task()");
|
||||
}
|
||||
|
||||
public int read_status(){
|
||||
var status_file = working_dir + "/status";
|
||||
var f = File.new_for_path(status_file);
|
||||
if (f.query_exists()){
|
||||
var txt = file_read(status_file);
|
||||
return int.parse(txt);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ using TeeJee.System;
|
||||
using TeeJee.Misc;
|
||||
|
||||
public class CryptTabEntry : GLib.Object{
|
||||
|
||||
public bool is_comment = false;
|
||||
public bool is_empty_line = false;
|
||||
|
||||
@ -56,6 +57,7 @@ public class CryptTabEntry : GLib.Object{
|
||||
}
|
||||
|
||||
public static Gee.ArrayList<CryptTabEntry> read_file(string file_path){
|
||||
|
||||
var list = new Gee.ArrayList<CryptTabEntry>();
|
||||
|
||||
if (!file_exists(file_path)){ return list; }
|
||||
@ -103,9 +105,7 @@ public class CryptTabEntry : GLib.Object{
|
||||
return list;
|
||||
}
|
||||
|
||||
public static string write_file(
|
||||
Gee.ArrayList<CryptTabEntry> entries, string file_path,
|
||||
bool keep_comments_and_empty_lines = true){
|
||||
public static string write_file(Gee.ArrayList<CryptTabEntry> entries, string file_path, bool keep_comments_and_empty_lines = true){
|
||||
|
||||
string text = "";
|
||||
foreach(var entry in entries){
|
||||
|
@ -1423,9 +1423,9 @@ public class Device : GLib.Object{
|
||||
// use password to unlock
|
||||
|
||||
var cmd = "echo -n -e '%s' | cryptsetup luksOpen --key-file - '%s' '%s'\n".printf(
|
||||
luks_pass, luks_device.device, luks_name);
|
||||
escape_single_quote(luks_pass), luks_device.device, luks_name);
|
||||
|
||||
log_debug(cmd.replace(luks_pass, "**PASSWORD**"));
|
||||
log_debug(cmd.replace(escape_single_quote(luks_pass), "**PASSWORD**"));
|
||||
|
||||
int status = exec_script_sync(cmd, out std_out, out std_err, false, true);
|
||||
|
||||
@ -1469,9 +1469,9 @@ public class Device : GLib.Object{
|
||||
// use password to unlock
|
||||
|
||||
var cmd = "echo -n -e '%s' | cryptsetup luksOpen --key-file - '%s' '%s'\n".printf(
|
||||
luks_pass, luks_device.device, luks_name);
|
||||
escape_single_quote(luks_pass), luks_device.device, luks_name);
|
||||
|
||||
log_debug(cmd.replace(luks_pass, "**PASSWORD**"));
|
||||
log_debug(cmd.replace(escape_single_quote(luks_pass), "**PASSWORD**"));
|
||||
|
||||
int status = exec_script_sync(cmd, out std_out, out std_err, false, true);
|
||||
|
||||
@ -1515,6 +1515,7 @@ public class Device : GLib.Object{
|
||||
}
|
||||
|
||||
public static bool luks_lock(string kname, Gtk.Window? parent_window){
|
||||
|
||||
var cmd = "cryptsetup luksClose %s".printf(kname);
|
||||
|
||||
log_debug(cmd);
|
||||
|
@ -51,65 +51,19 @@ public class FileItem : GLib.Object,Gee.Comparable<FileItem> {
|
||||
public bool is_selected = false;
|
||||
public bool is_symlink = false;
|
||||
public string symlink_target = "";
|
||||
public bool is_archive = false;
|
||||
public bool is_stale = false;
|
||||
|
||||
public FileItem parent;
|
||||
public Gee.HashMap<string, FileItem> children = new Gee.HashMap<string, FileItem>();
|
||||
public FileItem? source_archive;
|
||||
|
||||
public GLib.Object? tag;
|
||||
//public Gtk.TreeIter? treeiter;
|
||||
|
||||
public long file_count = 0;
|
||||
public long dir_count = 0;
|
||||
private int64 _size = 0;
|
||||
private int64 _size_compressed = 0;
|
||||
|
||||
public long file_count_total = 0;
|
||||
public long dir_count_total = 0;
|
||||
|
||||
//public string icon_name = "gtk-file";
|
||||
public GLib.Icon icon;
|
||||
|
||||
public bool is_dummy = false;
|
||||
|
||||
public static string[] archive_extensions = {
|
||||
".tar",
|
||||
".tar.gz", ".tgz",
|
||||
".tar.bzip2", ".tar.bz2", ".tbz", ".tbz2", ".tb2",
|
||||
".tar.lzma", ".tar.lz", ".tlz",
|
||||
".tar.xz", ".txz",
|
||||
".tar.7z",
|
||||
".tar.zip",
|
||||
".7z", ".lzma",
|
||||
".bz2", ".bzip2",
|
||||
".gz", ".gzip",
|
||||
".zip", ".rar", ".cab", ".arj", ".z", ".taz", ".cpio",
|
||||
".rpm", ".deb",
|
||||
".lzh", ".lha",
|
||||
".chm", ".chw", ".hxs",
|
||||
".iso", ".dmg", ".xar", ".hfs", ".ntfs", ".fat", ".vhd", ".mbr",
|
||||
".wim", ".swm", ".squashfs", ".cramfs", ".scap"
|
||||
};
|
||||
|
||||
|
||||
// contructors -------------------------------
|
||||
|
||||
public FileItem(string name = "New Archive") {
|
||||
public FileItem(string name) {
|
||||
file_name = name;
|
||||
}
|
||||
|
||||
public FileItem.dummy(FileType _file_type) {
|
||||
is_dummy = true;
|
||||
file_type = _file_type;
|
||||
}
|
||||
|
||||
public FileItem.dummy_root() {
|
||||
file_name = "dummy";
|
||||
file_location = "";
|
||||
}
|
||||
|
||||
public FileItem.from_disk_path_with_basic_info(string _file_path) {
|
||||
file_path = _file_path;
|
||||
file_name = file_basename(_file_path);
|
||||
@ -124,7 +78,7 @@ public class FileItem : GLib.Object,Gee.Comparable<FileItem> {
|
||||
file_type = _file_type;
|
||||
}
|
||||
|
||||
// properties --------------------------------------
|
||||
// properties -------------------------------------------------
|
||||
|
||||
public int64 size {
|
||||
get{
|
||||
@ -132,13 +86,7 @@ public class FileItem : GLib.Object,Gee.Comparable<FileItem> {
|
||||
}
|
||||
}
|
||||
|
||||
public int64 size_compressed {
|
||||
get{
|
||||
return _size_compressed;
|
||||
}
|
||||
}
|
||||
|
||||
// helpers ---------------
|
||||
// helpers ----------------------------------------------------
|
||||
|
||||
public int compare_to(FileItem b){
|
||||
if (this.file_type != b.file_type) {
|
||||
@ -159,210 +107,7 @@ public class FileItem : GLib.Object,Gee.Comparable<FileItem> {
|
||||
}
|
||||
}
|
||||
|
||||
// instance methods ------------------------------------------
|
||||
|
||||
public FileItem add_child_from_disk(string item_file_path, int depth = -1) {
|
||||
FileItem item = null;
|
||||
|
||||
//log_debug("add_child_from_disk: %02d: %s".printf(depth, item_file_path));
|
||||
|
||||
try {
|
||||
FileEnumerator enumerator;
|
||||
FileInfo info;
|
||||
File file = File.parse_name (item_file_path);
|
||||
|
||||
if (file.query_exists()) {
|
||||
|
||||
// query file type
|
||||
var item_file_type = file.query_file_type(FileQueryInfoFlags.NONE);
|
||||
|
||||
//add item
|
||||
item = this.add_child(item_file_path, item_file_type, 0, 0, true);
|
||||
|
||||
if ((item.file_type == FileType.DIRECTORY) && !item.is_symlink) {
|
||||
if (depth != 0){
|
||||
//recurse children
|
||||
enumerator = file.enumerate_children ("%s".printf(FileAttribute.STANDARD_NAME), 0);
|
||||
while ((info = enumerator.next_file()) != null) {
|
||||
string child_path = "%s/%s".printf(item_file_path, info.get_name());
|
||||
item.add_child_from_disk(child_path, depth - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Error e) {
|
||||
log_error (e.message);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public FileItem add_descendant(
|
||||
string _file_path,
|
||||
FileType ? _file_type,
|
||||
int64 item_size,
|
||||
int64 item_size_compressed) {
|
||||
|
||||
//log_debug("add_descendant=%s".printf(_file_path));
|
||||
|
||||
string item_path = _file_path.strip();
|
||||
FileType item_type = (_file_type == null) ? FileType.REGULAR : _file_type;
|
||||
|
||||
if (item_path.has_suffix("/")) {
|
||||
item_path = item_path[0:item_path.length - 1];
|
||||
item_type = FileType.DIRECTORY;
|
||||
}
|
||||
|
||||
if (item_path.has_prefix("/")) {
|
||||
item_path = item_path[1:item_path.length];
|
||||
}
|
||||
|
||||
string dir_name = "";
|
||||
string dir_path = "";
|
||||
|
||||
//create dirs and find parent dir
|
||||
FileItem current_dir = this;
|
||||
string[] arr = item_path.split("/");
|
||||
for (int i = 0; i < arr.length - 1; i++) {
|
||||
//get dir name
|
||||
dir_name = arr[i];
|
||||
|
||||
//add dir
|
||||
if (!current_dir.children.keys.contains(dir_name)) {
|
||||
if ((current_dir == this) && current_dir.is_archive){
|
||||
dir_path = "";
|
||||
}
|
||||
else {
|
||||
dir_path = current_dir.file_path + "/";
|
||||
}
|
||||
dir_path = "%s%s".printf(dir_path, dir_name);
|
||||
current_dir.add_child(dir_path, FileType.DIRECTORY, 0, 0, false);
|
||||
}
|
||||
|
||||
current_dir = current_dir.children[dir_name];
|
||||
}
|
||||
|
||||
//get item name
|
||||
string item_name = arr[arr.length - 1];
|
||||
|
||||
//add item
|
||||
if (!current_dir.children.keys.contains(item_name)) {
|
||||
|
||||
//log_debug("add_descendant: add_child()");
|
||||
|
||||
current_dir.add_child(
|
||||
item_path, item_type, item_size, item_size_compressed, false);
|
||||
}
|
||||
|
||||
//log_debug("add_descendant: finished: %s".printf(item_path));
|
||||
|
||||
return current_dir.children[item_name];
|
||||
}
|
||||
|
||||
public FileItem add_child(
|
||||
string item_file_path,
|
||||
FileType item_file_type,
|
||||
int64 item_size,
|
||||
int64 item_size_compressed,
|
||||
bool item_query_file_info){
|
||||
|
||||
// create new item ------------------------------
|
||||
|
||||
//log_debug("add_child: %s".printf(item_file_path));
|
||||
|
||||
FileItem item = new FileItem.from_path_and_type(item_file_path, item_file_type);
|
||||
//item.tag = this.tag;
|
||||
|
||||
foreach(var ext in archive_extensions){
|
||||
if (item_file_path.has_suffix(ext)) {
|
||||
item = new ArchiveFile(item_file_path);
|
||||
item.is_archive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check existing ----------------------------
|
||||
|
||||
bool existing_file = false;
|
||||
if (!children.has_key(item.file_name)){
|
||||
children[item.file_name] = item;
|
||||
|
||||
//set parent
|
||||
item.parent = this;
|
||||
}
|
||||
else{
|
||||
existing_file = true;
|
||||
item = this.children[item.file_name];
|
||||
|
||||
// mark as fresh
|
||||
item.is_stale = false;
|
||||
}
|
||||
|
||||
// copy prefix from parent
|
||||
item.file_path_prefix = this.file_path_prefix;
|
||||
|
||||
// query file properties
|
||||
if (item_query_file_info){
|
||||
//log_debug("add_child: query_file_info()");
|
||||
item.query_file_info();
|
||||
}
|
||||
|
||||
if (item_file_type == FileType.REGULAR) {
|
||||
|
||||
//log_debug("add_child: regular file");
|
||||
|
||||
// set file sizes
|
||||
if (item_size > 0) {
|
||||
item._size = item_size;
|
||||
}
|
||||
if (item_size_compressed > 0) {
|
||||
item._size_compressed = item_size_compressed;
|
||||
}
|
||||
|
||||
// update file counts
|
||||
if (!existing_file){
|
||||
this.file_count++;
|
||||
this.file_count_total++;
|
||||
this._size += item_size;
|
||||
this._size_compressed += item_size_compressed;
|
||||
|
||||
// update file count and size of parent dirs
|
||||
var temp = this;
|
||||
while (temp.parent != null) {
|
||||
temp.parent.file_count_total++;
|
||||
temp.parent._size += item_size;
|
||||
temp.parent._size_compressed += item_size_compressed;
|
||||
temp = temp.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (item_file_type == FileType.DIRECTORY) {
|
||||
|
||||
//log_debug("add_child: directory");
|
||||
|
||||
if (!existing_file){
|
||||
|
||||
// update dir counts
|
||||
this.dir_count++;
|
||||
this.dir_count_total++;
|
||||
//this.size += _size;
|
||||
//size will be updated when children are added
|
||||
|
||||
// update dir count of parent dirs
|
||||
var temp = this;
|
||||
while (temp.parent != null) {
|
||||
temp.parent.dir_count_total++;
|
||||
temp = temp.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//log_debug("add_child: finished: fc=%lld dc=%lld path=%s".printf(
|
||||
// file_count, dir_count, item_file_path));
|
||||
|
||||
return item;
|
||||
}
|
||||
// instance methods -------------------------------------------
|
||||
|
||||
public void query_file_info() {
|
||||
|
||||
@ -477,186 +222,7 @@ public class FileItem : GLib.Object,Gee.Comparable<FileItem> {
|
||||
}
|
||||
}
|
||||
|
||||
public void query_children(int depth = -1) {
|
||||
FileEnumerator enumerator;
|
||||
FileInfo info;
|
||||
File file = File.parse_name (file_path);
|
||||
|
||||
if (!file.query_exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_type == FileType.DIRECTORY) {
|
||||
if (depth == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
// mark existing children as stale
|
||||
foreach(var child in children.values){
|
||||
child.is_stale = true;
|
||||
}
|
||||
|
||||
// recurse children
|
||||
enumerator = file.enumerate_children ("%s".printf(FileAttribute.STANDARD_NAME), 0);
|
||||
while ((info = enumerator.next_file()) != null) {
|
||||
string child_name = info.get_name();
|
||||
string child_path = GLib.Path.build_filename(file_path, child_name);
|
||||
this.add_child_from_disk(child_path, depth - 1);
|
||||
}
|
||||
|
||||
// remove stale children
|
||||
var list = new Gee.ArrayList<string>();
|
||||
foreach(var key in children.keys){
|
||||
if (children[key].is_stale){
|
||||
list.add(key);
|
||||
}
|
||||
}
|
||||
foreach(var key in list){
|
||||
//log_debug("Unset:%s".printf(key));
|
||||
children.unset(key);
|
||||
}
|
||||
}
|
||||
catch (Error e) {
|
||||
log_error (e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear_children() {
|
||||
this.children.clear();
|
||||
}
|
||||
|
||||
public FileItem remove_child(string child_name) {
|
||||
FileItem child = null;
|
||||
|
||||
if (this.children.has_key(child_name)) {
|
||||
child = this.children[child_name];
|
||||
this.children.unset(child_name);
|
||||
|
||||
if (child.file_type == FileType.REGULAR) {
|
||||
//update file counts
|
||||
this.file_count--;
|
||||
this.file_count_total--;
|
||||
|
||||
//subtract child size
|
||||
this._size -= child.size;
|
||||
this._size_compressed -= child.size_compressed;
|
||||
|
||||
//update file count and size of parent dirs
|
||||
var temp = this;
|
||||
while (temp.parent != null) {
|
||||
temp.parent.file_count_total--;
|
||||
|
||||
temp.parent._size -= child.size;
|
||||
temp.parent._size_compressed -= child.size_compressed;
|
||||
|
||||
temp = temp.parent;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//update dir counts
|
||||
this.dir_count--;
|
||||
this.dir_count_total--;
|
||||
|
||||
//subtract child counts
|
||||
this.file_count_total -= child.file_count_total;
|
||||
this.dir_count_total -= child.dir_count_total;
|
||||
this._size -= child.size;
|
||||
this._size_compressed -= child.size_compressed;
|
||||
|
||||
//update dir count of parent dirs
|
||||
var temp = this;
|
||||
while (temp.parent != null) {
|
||||
temp.parent.dir_count_total--;
|
||||
|
||||
temp.parent.file_count_total -= child.file_count_total;
|
||||
temp.parent.dir_count_total -= child.dir_count_total;
|
||||
temp.parent._size -= child.size;
|
||||
temp.parent._size_compressed -= child.size_compressed;
|
||||
|
||||
temp = temp.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//log_debug("%3ld %3ld %s".printf(file_count, dir_count, file_path));
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
public FileItem? find_descendant(string path){
|
||||
var child = this;
|
||||
|
||||
foreach(var part in path.split("/")){
|
||||
|
||||
// query children if needed
|
||||
if (child.children.size == 0){
|
||||
child.query_children(1);
|
||||
if (child.children.size == 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (child.children.has_key(part)){
|
||||
child = child.children[part];
|
||||
}
|
||||
}
|
||||
|
||||
if (child.file_path == path){
|
||||
return child;
|
||||
}
|
||||
else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void set_file_path_prefix(string prefix){
|
||||
file_path_prefix = prefix;
|
||||
foreach(var child in this.children.values){
|
||||
child.set_file_path_prefix(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
public void print(int level) {
|
||||
|
||||
if (level == 0) {
|
||||
stdout.printf("\n");
|
||||
stdout.flush();
|
||||
}
|
||||
|
||||
stdout.printf("%s%s\n".printf(string.nfill(level * 2, ' '), file_name));
|
||||
stdout.flush();
|
||||
|
||||
foreach (var key in this.children.keys) {
|
||||
this.children[key].print(level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public Gee.ArrayList<FileItem> get_children_sorted(){
|
||||
var list = new Gee.ArrayList<FileItem>();
|
||||
|
||||
foreach(string key in children.keys) {
|
||||
var item = children[key];
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
list.sort((a, b) => {
|
||||
if ((a.file_type == FileType.DIRECTORY) && (b.file_type != FileType.DIRECTORY)){
|
||||
return -1;
|
||||
}
|
||||
else if ((a.file_type != FileType.DIRECTORY) && (b.file_type == FileType.DIRECTORY)){
|
||||
return 1;
|
||||
}
|
||||
else{
|
||||
return strcmp(a.file_name.down(), b.file_name.down());
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// icons
|
||||
// icons ------------------------------------------------------
|
||||
|
||||
public Gdk.Pixbuf? get_icon(int icon_size, bool add_transparency, bool add_emblems){
|
||||
|
||||
@ -678,6 +244,3 @@ public class FileItem : GLib.Object,Gee.Comparable<FileItem> {
|
||||
return pixbuf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -191,8 +191,7 @@ public class FsTabEntry : GLib.Object{
|
||||
}
|
||||
}
|
||||
|
||||
public static FsTabEntry? find_entry_by_mount_point(
|
||||
Gee.ArrayList<FsTabEntry> entries, string mount_path){
|
||||
public static FsTabEntry? find_entry_by_mount_point(Gee.ArrayList<FsTabEntry> entries, string mount_path){
|
||||
|
||||
foreach(var entry in entries){
|
||||
if (entry.mount_point == mount_path){
|
||||
@ -203,6 +202,7 @@ public class FsTabEntry : GLib.Object{
|
||||
}
|
||||
|
||||
public Device? resolve_device(Gee.ArrayList<CryptTabEntry> crypttab, Gtk.Window? parent_window){
|
||||
|
||||
Device dev_fstab = null;
|
||||
if (device_uuid.length > 0){
|
||||
dev_fstab = Device.get_device_by_uuid(device_uuid);
|
||||
|
@ -82,23 +82,20 @@ public class DonationWindow : Gtk.Window {
|
||||
|
||||
add_label(msg);
|
||||
|
||||
msg = _("Since this a free application there is no dedicated support for this app. You can use the GitHub issue tracker for reporting issues, or post your questions on the Linux Mint forums. Please avoid reporting issues by email.");
|
||||
msg = _("You can use the GitHub issue tracker for reporting issues, or post your questions on the Linux Mint forums. Please avoid reporting issues by email.");
|
||||
|
||||
add_label(msg);
|
||||
|
||||
hbox = add_vbox();
|
||||
|
||||
add_button(hbox, _("GitHub"),
|
||||
"https://github.com/teejee2008/%s/issues".printf(appname.down()));
|
||||
add_button(hbox, _("GitHub"), "https://github.com/teejee2008/%s/issues".printf(appname.down()));
|
||||
|
||||
if (has_wiki){
|
||||
|
||||
add_button(hbox, _("Wiki"),
|
||||
"https://github.com/teejee2008/%s/wiki".printf(appname.down()));
|
||||
add_button(hbox, _("Wiki"), "https://github.com/teejee2008/%s/wiki".printf(appname.down()));
|
||||
}
|
||||
|
||||
add_button(hbox, _("Website"),
|
||||
"https://teejeetech.in/");
|
||||
add_button(hbox, _("Website"), "https://teejeetech.in/");
|
||||
|
||||
// close window ---------------------------------------------------------
|
||||
|
||||
|
@ -53,8 +53,7 @@ namespace TeeJee.GtkHelper{
|
||||
gtk_do_events ();
|
||||
}
|
||||
|
||||
public void gtk_messagebox(
|
||||
string title, string message, Gtk.Window? parent_win, bool is_error = false){
|
||||
public void gtk_messagebox(string title, string message, Gtk.Window? parent_win, bool is_error = false){
|
||||
|
||||
/* Shows a simple message box */
|
||||
|
||||
@ -81,8 +80,7 @@ namespace TeeJee.GtkHelper{
|
||||
dlg.destroy();
|
||||
}
|
||||
|
||||
public string? gtk_inputbox(
|
||||
string title, string message, Gtk.Window? parent_win, bool mask_password = false){
|
||||
public string? gtk_inputbox(string title, string message, Gtk.Window? parent_win, bool mask_password = false){
|
||||
|
||||
/* Shows a simple input prompt */
|
||||
|
||||
@ -194,10 +192,7 @@ namespace TeeJee.GtkHelper{
|
||||
return val;
|
||||
}
|
||||
|
||||
public GLib.Object gtk_combobox_get_selected_object (
|
||||
ComboBox combo,
|
||||
int index,
|
||||
GLib.Object default_value){
|
||||
public GLib.Object gtk_combobox_get_selected_object (ComboBox combo, int index, GLib.Object default_value){
|
||||
|
||||
/* Conveniance function to get combobox value */
|
||||
|
||||
@ -230,6 +225,7 @@ namespace TeeJee.GtkHelper{
|
||||
// styles ----------------
|
||||
|
||||
public static int CSS_AUTO_CLASS_INDEX = 0;
|
||||
|
||||
public static void gtk_apply_css(Gtk.Widget[] widgets, string css_style){
|
||||
var css_provider = new Gtk.CssProvider();
|
||||
var css = ".style_%d { %s }".printf(++CSS_AUTO_CLASS_INDEX, css_style);
|
||||
@ -262,98 +258,12 @@ namespace TeeJee.GtkHelper{
|
||||
return count;
|
||||
}
|
||||
|
||||
public void gtk_stripe_row(
|
||||
Gtk.CellRenderer cell,
|
||||
bool odd_row,
|
||||
string odd_color = "#F4F6F7",
|
||||
string even_color = "#FFFFFF"){
|
||||
|
||||
if (cell is Gtk.CellRendererText){
|
||||
(cell as Gtk.CellRendererText).background = odd_row ? odd_color : even_color;
|
||||
}
|
||||
else if (cell is Gtk.CellRendererPixbuf){
|
||||
(cell as Gtk.CellRendererPixbuf).cell_background = odd_row ? odd_color : even_color;
|
||||
}
|
||||
}
|
||||
|
||||
public void gtk_treeview_redraw(Gtk.TreeView treeview){
|
||||
var model = treeview.model;
|
||||
treeview.model = null;
|
||||
treeview.model = model;
|
||||
}
|
||||
|
||||
// menu
|
||||
|
||||
public void gtk_menu_add_separator(Gtk.Menu menu){
|
||||
Gdk.RGBA gray = Gdk.RGBA();
|
||||
gray.parse ("rgba(200,200,200,1)");
|
||||
|
||||
// separator
|
||||
var menu_item = new Gtk.SeparatorMenuItem();
|
||||
menu_item.override_color (StateFlags.NORMAL, gray);
|
||||
menu.append(menu_item);
|
||||
}
|
||||
|
||||
public Gtk.MenuItem gtk_menu_add_item(
|
||||
Gtk.Menu menu,
|
||||
string label,
|
||||
string tooltip,
|
||||
Gtk.Image? icon_image,
|
||||
Gtk.SizeGroup? sg_icon = null,
|
||||
Gtk.SizeGroup? sg_label = null){
|
||||
|
||||
var menu_item = new Gtk.MenuItem();
|
||||
menu.append(menu_item);
|
||||
|
||||
var box = new Gtk.Box(Orientation.HORIZONTAL, 3);
|
||||
menu_item.add(box);
|
||||
|
||||
// add icon
|
||||
|
||||
if (icon_image == null){
|
||||
var dummy = new Gtk.Label("");
|
||||
box.add(dummy);
|
||||
|
||||
if (sg_icon != null){
|
||||
sg_icon.add_widget(dummy);
|
||||
}
|
||||
}
|
||||
else{
|
||||
box.add(icon_image);
|
||||
|
||||
if (sg_icon != null){
|
||||
sg_icon.add_widget(icon_image);
|
||||
}
|
||||
}
|
||||
|
||||
// add label
|
||||
|
||||
var lbl = new Gtk.Label(label);
|
||||
lbl.xalign = (float) 0.0;
|
||||
lbl.margin_right = 6;
|
||||
box.add(lbl);
|
||||
|
||||
if (sg_label != null){
|
||||
sg_label.add_widget(lbl);
|
||||
}
|
||||
|
||||
box.set_tooltip_text(tooltip);
|
||||
|
||||
return menu_item;
|
||||
}
|
||||
|
||||
// build ui
|
||||
|
||||
public Gtk.Label gtk_box_add_header(Gtk.Box box, string text){
|
||||
var label = new Gtk.Label("<b>" + text + "</b>");
|
||||
label.set_use_markup(true);
|
||||
label.xalign = (float) 0.0;
|
||||
label.margin_bottom = 6;
|
||||
box.add(label);
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
// misc
|
||||
|
||||
public bool gtk_container_has_child(Gtk.Container container, Gtk.Widget widget){
|
||||
@ -365,31 +275,6 @@ namespace TeeJee.GtkHelper{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void text_view_append(Gtk.TextView view, string text){
|
||||
TextIter iter;
|
||||
view.buffer.get_end_iter(out iter);
|
||||
view.buffer.insert(ref iter, text, text.length);
|
||||
}
|
||||
|
||||
private void text_view_prepend(Gtk.TextView view, string text){
|
||||
TextIter iter;
|
||||
view.buffer.get_start_iter(out iter);
|
||||
view.buffer.insert(ref iter, text, text.length);
|
||||
}
|
||||
|
||||
private void text_view_scroll_to_end(Gtk.TextView view){
|
||||
TextIter iter;
|
||||
view.buffer.get_end_iter(out iter);
|
||||
view.scroll_to_iter(iter, 0.0, false, 0.0, 0.0);
|
||||
}
|
||||
|
||||
private void text_view_scroll_to_start(Gtk.TextView view){
|
||||
TextIter iter;
|
||||
view.buffer.get_start_iter(out iter);
|
||||
view.scroll_to_iter(iter, 0.0, false, 0.0, 0.0);
|
||||
}
|
||||
|
||||
// file chooser ----------------
|
||||
|
||||
public Gtk.FileFilter create_file_filter(string group_name, string[] patterns) {
|
||||
@ -404,8 +289,7 @@ namespace TeeJee.GtkHelper{
|
||||
// utility ------------------
|
||||
|
||||
// add_notebook
|
||||
private Gtk.Notebook add_notebook(
|
||||
Gtk.Box box, bool show_tabs = true, bool show_border = true){
|
||||
private Gtk.Notebook add_notebook(Gtk.Box box, bool show_tabs = true, bool show_border = true){
|
||||
|
||||
// notebook
|
||||
var book = new Gtk.Notebook();
|
||||
@ -418,24 +302,8 @@ namespace TeeJee.GtkHelper{
|
||||
return book;
|
||||
}
|
||||
|
||||
// add_tab
|
||||
private Gtk.Box add_tab(
|
||||
Gtk.Notebook book, string title, int margin = 12, int spacing = 6){
|
||||
|
||||
// label
|
||||
var label = new Gtk.Label(title);
|
||||
|
||||
// vbox
|
||||
var vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, spacing);
|
||||
vbox.margin = margin;
|
||||
book.append_page (vbox, label);
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
||||
// add_treeview
|
||||
private Gtk.TreeView add_treeview(Gtk.Box box,
|
||||
Gtk.SelectionMode selection_mode = Gtk.SelectionMode.SINGLE){
|
||||
private Gtk.TreeView add_treeview(Gtk.Box box, Gtk.SelectionMode selection_mode = Gtk.SelectionMode.SINGLE){
|
||||
|
||||
// TreeView
|
||||
var treeview = new TreeView();
|
||||
@ -455,8 +323,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_column_text
|
||||
private Gtk.TreeViewColumn add_column_text(
|
||||
Gtk.TreeView treeview, string title, out Gtk.CellRendererText cell){
|
||||
private Gtk.TreeViewColumn add_column_text(Gtk.TreeView treeview, string title, out Gtk.CellRendererText cell){
|
||||
|
||||
// TreeViewColumn
|
||||
var col = new Gtk.TreeViewColumn();
|
||||
@ -470,10 +337,8 @@ namespace TeeJee.GtkHelper{
|
||||
return col;
|
||||
}
|
||||
|
||||
|
||||
// add_column_icon
|
||||
private Gtk.TreeViewColumn add_column_icon(
|
||||
Gtk.TreeView treeview, string title, out Gtk.CellRendererPixbuf cell){
|
||||
private Gtk.TreeViewColumn add_column_icon(Gtk.TreeView treeview, string title, out Gtk.CellRendererPixbuf cell){
|
||||
|
||||
// TreeViewColumn
|
||||
var col = new Gtk.TreeViewColumn();
|
||||
@ -488,8 +353,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_column_icon_and_text
|
||||
private Gtk.TreeViewColumn add_column_icon_and_text(
|
||||
Gtk.TreeView treeview, string title,
|
||||
private Gtk.TreeViewColumn add_column_icon_and_text(Gtk.TreeView treeview, string title,
|
||||
out Gtk.CellRendererPixbuf cell_pix, out Gtk.CellRendererText cell_text){
|
||||
|
||||
// TreeViewColumn
|
||||
@ -509,8 +373,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_column_radio_and_text
|
||||
private Gtk.TreeViewColumn add_column_radio_and_text(
|
||||
Gtk.TreeView treeview, string title,
|
||||
private Gtk.TreeViewColumn add_column_radio_and_text(Gtk.TreeView treeview, string title,
|
||||
out Gtk.CellRendererToggle cell_radio, out Gtk.CellRendererText cell_text){
|
||||
|
||||
// TreeViewColumn
|
||||
@ -532,11 +395,8 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_column_icon_radio_text
|
||||
private Gtk.TreeViewColumn add_column_icon_radio_text(
|
||||
Gtk.TreeView treeview, string title,
|
||||
out Gtk.CellRendererPixbuf cell_pix,
|
||||
out Gtk.CellRendererToggle cell_radio,
|
||||
out Gtk.CellRendererText cell_text){
|
||||
private Gtk.TreeViewColumn add_column_icon_radio_text(Gtk.TreeView treeview, string title,
|
||||
out Gtk.CellRendererPixbuf cell_pix, out Gtk.CellRendererToggle cell_radio, out Gtk.CellRendererText cell_text){
|
||||
|
||||
// TreeViewColumn
|
||||
var col = new Gtk.TreeViewColumn();
|
||||
@ -561,9 +421,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_label_scrolled
|
||||
private Gtk.Label add_label_scrolled(
|
||||
Gtk.Box box, string text,
|
||||
bool show_border = false, bool wrap = false, int ellipsize_chars = 40){
|
||||
private Gtk.Label add_label_scrolled(Gtk.Box box, string text, bool show_border = false, bool wrap = false, int ellipsize_chars = 40){
|
||||
|
||||
// ScrolledWindow
|
||||
var scroll = new Gtk.ScrolledWindow(null, null);
|
||||
@ -599,33 +457,8 @@ namespace TeeJee.GtkHelper{
|
||||
return label;
|
||||
}
|
||||
|
||||
// add_text_view
|
||||
private Gtk.TextView add_text_view(
|
||||
Gtk.Box box, string text){
|
||||
|
||||
// ScrolledWindow
|
||||
var scrolled = new Gtk.ScrolledWindow(null, null);
|
||||
scrolled.hscrollbar_policy = PolicyType.NEVER;
|
||||
scrolled.vscrollbar_policy = PolicyType.ALWAYS;
|
||||
scrolled.expand = true;
|
||||
box.add(scrolled);
|
||||
|
||||
var view = new Gtk.TextView();
|
||||
view.wrap_mode = Gtk.WrapMode.WORD_CHAR;
|
||||
view.accepts_tab = false;
|
||||
view.editable = false;
|
||||
view.cursor_visible = false;
|
||||
view.buffer.text = text;
|
||||
view.sensitive = false;
|
||||
scrolled.add (view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
// add_label
|
||||
private Gtk.Label add_label(
|
||||
Gtk.Box box, string text, bool bold = false,
|
||||
bool italic = false, bool large = false){
|
||||
private Gtk.Label add_label(Gtk.Box box, string text, bool bold = false, bool italic = false, bool large = false){
|
||||
|
||||
string msg = "<span%s%s%s>%s</span>".printf(
|
||||
(bold ? " weight=\"bold\"" : ""),
|
||||
@ -642,9 +475,7 @@ namespace TeeJee.GtkHelper{
|
||||
return label;
|
||||
}
|
||||
|
||||
private string format_text(
|
||||
string text,
|
||||
bool bold = false, bool italic = false, bool large = false){
|
||||
private string format_text(string text, bool bold = false, bool italic = false, bool large = false){
|
||||
|
||||
string msg = "<span%s%s%s>%s</span>".printf(
|
||||
(bold ? " weight=\"bold\"" : ""),
|
||||
@ -656,8 +487,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_label_header
|
||||
private Gtk.Label add_label_header(
|
||||
Gtk.Box box, string text, bool large_heading = false){
|
||||
private Gtk.Label add_label_header(Gtk.Box box, string text, bool large_heading = false){
|
||||
|
||||
var label = add_label(box, escape_html(text), true, false, large_heading);
|
||||
label.margin_bottom = 12;
|
||||
@ -665,8 +495,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_label_subnote
|
||||
private Gtk.Label add_label_subnote(
|
||||
Gtk.Box box, string text){
|
||||
private Gtk.Label add_label_subnote(Gtk.Box box, string text){
|
||||
|
||||
var label = add_label(box, text, false, true);
|
||||
label.margin_left = 6;
|
||||
@ -674,8 +503,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_radio
|
||||
private Gtk.RadioButton add_radio(
|
||||
Gtk.Box box, string text, Gtk.RadioButton? another_radio_in_group){
|
||||
private Gtk.RadioButton add_radio(Gtk.Box box, string text, Gtk.RadioButton? another_radio_in_group){
|
||||
|
||||
Gtk.RadioButton radio = null;
|
||||
|
||||
@ -702,8 +530,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_checkbox
|
||||
private Gtk.CheckButton add_checkbox(
|
||||
Gtk.Box box, string text){
|
||||
private Gtk.CheckButton add_checkbox(Gtk.Box box, string text){
|
||||
|
||||
var chk = new Gtk.CheckButton.with_label(text);
|
||||
chk.label = text;
|
||||
@ -727,9 +554,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_spin
|
||||
private Gtk.SpinButton add_spin(
|
||||
Gtk.Box box, double min, double max, double val,
|
||||
int digits = 0, double step = 1, double step_page = 1){
|
||||
private Gtk.SpinButton add_spin(Gtk.Box box, double min, double max, double val, int digits = 0, double step = 1, double step_page = 1){
|
||||
|
||||
var adj = new Gtk.Adjustment(val, min, max, step, step_page, 0);
|
||||
var spin = new Gtk.SpinButton(adj, step, digits);
|
||||
@ -746,10 +571,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_button
|
||||
private Gtk.Button add_button(
|
||||
Gtk.Box box, string text, string tooltip,
|
||||
Gtk.SizeGroup? size_group,
|
||||
Gtk.Image? icon = null){
|
||||
private Gtk.Button add_button(Gtk.Box box, string text, string tooltip, Gtk.SizeGroup? size_group, Gtk.Image? icon = null){
|
||||
|
||||
var button = new Gtk.Button();
|
||||
box.add(button);
|
||||
@ -770,10 +592,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_toggle_button
|
||||
private Gtk.ToggleButton add_toggle_button(
|
||||
Gtk.Box box, string text, string tooltip,
|
||||
Gtk.SizeGroup? size_group,
|
||||
Gtk.Image? icon = null){
|
||||
private Gtk.ToggleButton add_toggle_button(Gtk.Box box, string text, string tooltip, Gtk.SizeGroup? size_group, Gtk.Image? icon = null){
|
||||
|
||||
var button = new Gtk.ToggleButton();
|
||||
box.add(button);
|
||||
@ -794,8 +613,7 @@ namespace TeeJee.GtkHelper{
|
||||
}
|
||||
|
||||
// add_directory_chooser
|
||||
private Gtk.Entry add_directory_chooser(
|
||||
Gtk.Box box, string selected_directory, Gtk.Window parent_window){
|
||||
private Gtk.Entry add_directory_chooser(Gtk.Box box, string selected_directory, Gtk.Window parent_window){
|
||||
|
||||
// Entry
|
||||
var entry = new Gtk.Entry();
|
||||
@ -837,6 +655,5 @@ namespace TeeJee.GtkHelper{
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -201,8 +201,7 @@ public class IconManager : GLib.Object {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Gdk.Pixbuf? add_emblem (Gdk.Pixbuf pixbuf, string icon_name, int emblem_size,
|
||||
bool emblem_symbolic, Gtk.CornerType corner_type) {
|
||||
public static Gdk.Pixbuf? add_emblem (Gdk.Pixbuf pixbuf, string icon_name, int emblem_size, bool emblem_symbolic, Gtk.CornerType corner_type) {
|
||||
|
||||
if (icon_name.length == 0){ return pixbuf; }
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
/*
|
||||
* ProcStats.vala
|
||||
* LinuxDistro.vala
|
||||
*
|
||||
* Copyright 2012-2018 Tony George <teejeetech@gmail.com>
|
||||
*
|
||||
@ -36,6 +36,7 @@ public class LinuxDistro : GLib.Object{
|
||||
public string codename = "";
|
||||
|
||||
public LinuxDistro(){
|
||||
|
||||
dist_id = "";
|
||||
description = "";
|
||||
release = "";
|
||||
@ -43,6 +44,7 @@ public class LinuxDistro : GLib.Object{
|
||||
}
|
||||
|
||||
public string full_name(){
|
||||
|
||||
if (dist_id == ""){
|
||||
return "";
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ public class MountEntry : GLib.Object{
|
||||
public string mount_options = "";
|
||||
|
||||
public MountEntry(Device? device, string mount_point, string mount_options){
|
||||
|
||||
this.device = device;
|
||||
this.mount_point = mount_point;
|
||||
this.mount_options = mount_options;
|
||||
@ -37,6 +38,7 @@ public class MountEntry : GLib.Object{
|
||||
}
|
||||
|
||||
public string lvm_name(){
|
||||
|
||||
if ((device != null) && (device.type == "lvm") && (device.mapped_name.length > 0)){
|
||||
return device.mapped_name.strip();
|
||||
}
|
||||
@ -45,14 +47,14 @@ public class MountEntry : GLib.Object{
|
||||
}
|
||||
}
|
||||
|
||||
public static MountEntry? find_entry_by_mount_point(
|
||||
Gee.ArrayList<MountEntry> entries, string mount_path){
|
||||
public static MountEntry? find_entry_by_mount_point(Gee.ArrayList<MountEntry> entries, string mount_path){
|
||||
|
||||
foreach(var entry in entries){
|
||||
if (entry.mount_point == mount_path){
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ using TeeJee.ProcessHelper;
|
||||
|
||||
// dep: notify-send
|
||||
public class OSDNotify : GLib.Object {
|
||||
|
||||
private static DateTime dt_last_notification = null;
|
||||
public const int NOTIFICATION_INTERVAL = 3;
|
||||
|
||||
@ -53,7 +54,9 @@ public class OSDNotify : GLib.Object {
|
||||
}
|
||||
|
||||
long seconds = 9999;
|
||||
|
||||
if (dt_last_notification != null){
|
||||
|
||||
DateTime dt_end = new DateTime.now_local();
|
||||
TimeSpan elapsed = dt_end.difference(dt_last_notification);
|
||||
seconds = (long)(elapsed * 1.0 / TimeSpan.SECOND);
|
||||
@ -79,12 +82,9 @@ public class OSDNotify : GLib.Object {
|
||||
}
|
||||
|
||||
public static bool is_supported(){
|
||||
|
||||
string path = get_cmd_path("notify-send");
|
||||
if ((path != null) && (path.length > 0)){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (path != null) && (path.length > 0);
|
||||
}
|
||||
}
|
||||
|
@ -1,89 +0,0 @@
|
||||
|
||||
/*
|
||||
* ProcStats.vala
|
||||
*
|
||||
* Copyright 2012-2018 Tony George <teejeetech@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
using TeeJee.Logging;
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.ProcessHelper;
|
||||
|
||||
public class ProcStats : GLib.Object {
|
||||
public double user = 0;
|
||||
public double nice = 0;
|
||||
public double system = 0;
|
||||
public double idle = 0;
|
||||
public double iowait = 0;
|
||||
|
||||
public double user_delta = 0;
|
||||
public double nice_delta = 0;
|
||||
public double system_delta = 0;
|
||||
public double idle_delta = 0;
|
||||
public double iowait_delta = 0;
|
||||
|
||||
public double usage_percent = 0;
|
||||
|
||||
public static ProcStats stat_prev = null;
|
||||
|
||||
public ProcStats(string line){
|
||||
string[] arr = line.split(" ");
|
||||
int col = 0;
|
||||
if (arr[col++] == "cpu"){
|
||||
if (arr[col].length == 0){ col++; };
|
||||
|
||||
user = double.parse(arr[col++]);
|
||||
nice = double.parse(arr[col++]);
|
||||
system = double.parse(arr[col++]);
|
||||
idle = double.parse(arr[col++]);
|
||||
iowait = double.parse(arr[col++]);
|
||||
|
||||
if (ProcStats.stat_prev != null){
|
||||
user_delta = user - ProcStats.stat_prev.user;
|
||||
nice_delta = nice - ProcStats.stat_prev.nice;
|
||||
system_delta = system - ProcStats.stat_prev.system;
|
||||
idle_delta = idle - ProcStats.stat_prev.idle;
|
||||
iowait_delta = iowait - ProcStats.stat_prev.iowait;
|
||||
|
||||
usage_percent = (user_delta + nice_delta + system_delta) * 100 / (user_delta + nice_delta + system_delta + idle_delta);
|
||||
}
|
||||
else{
|
||||
usage_percent = 0;
|
||||
|
||||
}
|
||||
|
||||
ProcStats.stat_prev = this;
|
||||
}
|
||||
}
|
||||
|
||||
//returns 0 when it is called first time
|
||||
public static double get_cpu_usage(){
|
||||
string txt = file_read("/proc/stat");
|
||||
foreach(string line in txt.split("\n")){
|
||||
string[] arr = line.split(" ");
|
||||
if (arr[0] == "cpu"){
|
||||
ProcStats stat = new ProcStats(line);
|
||||
return stat.usage_percent;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,318 +0,0 @@
|
||||
|
||||
/*
|
||||
* SystemGroup.vala
|
||||
*
|
||||
* Copyright 2012-2018 Tony George <teejeetech@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
using TeeJee.Logging;
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.ProcessHelper;
|
||||
|
||||
public class SystemGroup : GLib.Object {
|
||||
|
||||
public string name = "";
|
||||
public string password = "";
|
||||
public int gid = -1;
|
||||
public string user_names = "";
|
||||
|
||||
public string shadow_line = "";
|
||||
public string password_hash = "";
|
||||
public string admin_list = "";
|
||||
public string member_list = "";
|
||||
|
||||
public bool is_selected = false;
|
||||
public Gee.ArrayList<string> users;
|
||||
|
||||
public static Gee.HashMap<string,SystemGroup> all_groups;
|
||||
|
||||
public SystemGroup(string name){
|
||||
this.name = name;
|
||||
this.users = new Gee.ArrayList<string>();
|
||||
}
|
||||
|
||||
public static void query_groups(bool no_passwords = true){
|
||||
if (no_passwords){
|
||||
all_groups = read_groups_from_file("/etc/group","","");
|
||||
}
|
||||
else{
|
||||
all_groups = read_groups_from_file("/etc/group","/etc/gshadow","");
|
||||
}
|
||||
}
|
||||
|
||||
public static Gee.ArrayList<SystemGroup> all_groups_sorted {
|
||||
owned get {
|
||||
var list = new Gee.ArrayList<SystemGroup>();
|
||||
foreach(var group in all_groups.values) {
|
||||
list.add(group);
|
||||
}
|
||||
list.sort((a,b) => { return strcmp(a.name, b.name); });
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public bool is_installed{
|
||||
get{
|
||||
return SystemGroup.all_groups.has_key(name);
|
||||
}
|
||||
}
|
||||
|
||||
public static Gee.HashMap<string,SystemGroup> read_groups_from_file(string group_file, string gshadow_file, string password){
|
||||
var list = new Gee.HashMap<string,SystemGroup>();
|
||||
|
||||
// read 'group' file -------------------------------
|
||||
|
||||
string txt = "";
|
||||
|
||||
if (group_file.has_suffix(".tar.gpg")){
|
||||
txt = file_decrypt_untar_read(group_file, password);
|
||||
}
|
||||
else{
|
||||
txt = file_read(group_file);
|
||||
}
|
||||
|
||||
if (txt.length == 0){
|
||||
return list;
|
||||
}
|
||||
|
||||
foreach(string line in txt.split("\n")){
|
||||
if ((line == null) || (line.length == 0)){
|
||||
continue;
|
||||
}
|
||||
|
||||
var group = parse_line_group(line);
|
||||
if (group != null){
|
||||
list[group.name] = group;
|
||||
}
|
||||
}
|
||||
|
||||
if (gshadow_file.length == 0){
|
||||
return list;
|
||||
}
|
||||
|
||||
// read 'gshadow' file -------------------------------
|
||||
|
||||
txt = "";
|
||||
|
||||
if (gshadow_file.has_suffix(".tar.gpg")){
|
||||
txt = file_decrypt_untar_read(gshadow_file, password);
|
||||
}
|
||||
else{
|
||||
txt = file_read(gshadow_file);
|
||||
}
|
||||
|
||||
if (txt.length == 0){
|
||||
return list;
|
||||
}
|
||||
|
||||
foreach(string line in txt.split("\n")){
|
||||
if ((line == null) || (line.length == 0)){
|
||||
continue;
|
||||
}
|
||||
|
||||
parse_line_gshadow(line, list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static SystemGroup? parse_line_group(string line){
|
||||
if ((line == null) || (line.length == 0)){
|
||||
return null;
|
||||
}
|
||||
|
||||
SystemGroup group = null;
|
||||
|
||||
//cdrom:x:24:teejee,user2
|
||||
string[] fields = line.split(":");
|
||||
|
||||
if (fields.length == 4){
|
||||
group = new SystemGroup(fields[0].strip());
|
||||
group.password = fields[1].strip();
|
||||
group.gid = int.parse(fields[2].strip());
|
||||
group.user_names = fields[3].strip();
|
||||
foreach(string user_name in group.user_names.split(",")){
|
||||
group.users.add(user_name);
|
||||
}
|
||||
}
|
||||
else{
|
||||
log_error("'group' file contains a record with non-standard fields" + ": %d".printf(fields.length));
|
||||
return null;
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
private static SystemGroup? parse_line_gshadow(string line, Gee.HashMap<string,SystemGroup> list){
|
||||
if ((line == null) || (line.length == 0)){
|
||||
return null;
|
||||
}
|
||||
|
||||
SystemGroup group = null;
|
||||
|
||||
//adm:*::syslog,teejee
|
||||
//<groupname>:<encrypted-password>:<admins>:<members>
|
||||
string[] fields = line.split(":");
|
||||
|
||||
if (fields.length == 4){
|
||||
string group_name = fields[0].strip();
|
||||
if (list.has_key(group_name)){
|
||||
group = list[group_name];
|
||||
group.shadow_line = line;
|
||||
group.password_hash = fields[1].strip();
|
||||
group.admin_list = fields[2].strip();
|
||||
group.member_list = fields[3].strip();
|
||||
return group;
|
||||
}
|
||||
else{
|
||||
log_error("group in file 'gshadow' does not exist in file 'group'" + ": %s".printf(group_name));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else{
|
||||
log_error("'gshadow' file contains a record with non-standard fields" + ": %d".printf(fields.length));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int add_group(string group_name, bool system_account = false){
|
||||
string std_out, std_err;
|
||||
string cmd = "groupadd%s %s".printf((system_account)? " --system" : "", group_name);
|
||||
int status = exec_sync(cmd, out std_out, out std_err);
|
||||
if (status != 0){
|
||||
log_error(std_err);
|
||||
}
|
||||
else{
|
||||
//log_msg(std_out);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public int add(){
|
||||
return add_group(name,is_system);
|
||||
}
|
||||
|
||||
public static int add_user_to_group(string user_name, string group_name){
|
||||
string std_out, std_err;
|
||||
string cmd = "adduser %s %s".printf(user_name, group_name);
|
||||
log_debug(cmd);
|
||||
int status = exec_sync(cmd, out std_out, out std_err);
|
||||
if (status != 0){
|
||||
log_error(std_err);
|
||||
}
|
||||
else{
|
||||
//log_msg(std_out);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public int add_to_group(string user_name){
|
||||
return add_user_to_group(user_name, name);
|
||||
}
|
||||
|
||||
public bool is_system{
|
||||
get {
|
||||
return (gid < 1000);
|
||||
}
|
||||
}
|
||||
|
||||
public bool update_group_file(){
|
||||
string file_path = "/etc/group";
|
||||
string txt = file_read(file_path);
|
||||
|
||||
var txt_new = "";
|
||||
foreach(string line in txt.split("\n")){
|
||||
if (line.strip().length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string[] parts = line.split(":");
|
||||
|
||||
if (parts.length != 4){
|
||||
log_error("'group' file contains a record with non-standard fields" + ": %d".printf(parts.length));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parts[0].strip() == name){
|
||||
txt_new += get_group_line() + "\n";
|
||||
}
|
||||
else{
|
||||
txt_new += line + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
file_write(file_path, txt_new);
|
||||
|
||||
log_msg("Updated group settings in /etc/group" + ": %s".printf(name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string get_group_line(){
|
||||
string txt = "";
|
||||
txt += "%s".printf(name);
|
||||
txt += ":%s".printf(password);
|
||||
txt += ":%d".printf(gid);
|
||||
txt += ":%s".printf(user_names);
|
||||
return txt;
|
||||
}
|
||||
|
||||
public bool update_gshadow_file(){
|
||||
string file_path = "/etc/gshadow";
|
||||
string txt = file_read(file_path);
|
||||
|
||||
var txt_new = "";
|
||||
foreach(string line in txt.split("\n")){
|
||||
if (line.strip().length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string[] parts = line.split(":");
|
||||
|
||||
if (parts.length != 4){
|
||||
log_error("'gshadow' file contains a record with non-standard fields" + ": %d".printf(parts.length));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parts[0].strip() == name){
|
||||
txt_new += get_gshadow_line() + "\n";
|
||||
}
|
||||
else{
|
||||
txt_new += line + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
file_write(file_path, txt_new);
|
||||
|
||||
log_msg("Updated group settings in /etc/gshadow" + ": %s".printf(name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string get_gshadow_line(){
|
||||
string txt = "";
|
||||
txt += "%s".printf(name);
|
||||
txt += ":%s".printf(password_hash);
|
||||
txt += ":%s".printf(admin_list);
|
||||
txt += ":%s".printf(member_list);
|
||||
return txt;
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ public class SystemUser : GLib.Object {
|
||||
}
|
||||
|
||||
public static void query_users(bool no_passwords = true){
|
||||
|
||||
if (no_passwords){
|
||||
all_users = read_users_from_file("/etc/passwd","","");
|
||||
}
|
||||
@ -93,20 +94,14 @@ public class SystemUser : GLib.Object {
|
||||
}
|
||||
|
||||
public static Gee.HashMap<string,SystemUser> read_users_from_file(
|
||||
|
||||
string passwd_file, string shadow_file, string password){
|
||||
|
||||
var list = new Gee.HashMap<string,SystemUser>();
|
||||
|
||||
// read 'passwd' file ---------------------------------
|
||||
|
||||
string txt = "";
|
||||
|
||||
if (passwd_file.has_suffix(".tar.gpg")){
|
||||
txt = file_decrypt_untar_read(passwd_file, password);
|
||||
}
|
||||
else{
|
||||
txt = file_read(passwd_file);
|
||||
}
|
||||
string txt = file_read(passwd_file);
|
||||
|
||||
if (txt.length == 0){
|
||||
return list;
|
||||
@ -128,14 +123,7 @@ public class SystemUser : GLib.Object {
|
||||
|
||||
// read 'shadow' file ---------------------------------
|
||||
|
||||
txt = "";
|
||||
|
||||
if (shadow_file.has_suffix(".tar.gpg")){
|
||||
txt = file_decrypt_untar_read(shadow_file, password);
|
||||
}
|
||||
else{
|
||||
txt = file_read(shadow_file);
|
||||
}
|
||||
|
||||
if (txt.length == 0){
|
||||
return list;
|
||||
@ -152,6 +140,7 @@ public class SystemUser : GLib.Object {
|
||||
}
|
||||
|
||||
private static SystemUser? parse_line_passwd(string line){
|
||||
|
||||
if ((line == null) || (line.length == 0)){
|
||||
return null;
|
||||
}
|
||||
@ -198,6 +187,7 @@ public class SystemUser : GLib.Object {
|
||||
}
|
||||
|
||||
private static SystemUser? parse_line_shadow(string line, Gee.HashMap<string,SystemUser> list){
|
||||
|
||||
if ((line == null) || (line.length == 0)){
|
||||
return null;
|
||||
}
|
||||
@ -235,24 +225,6 @@ public class SystemUser : GLib.Object {
|
||||
}
|
||||
}
|
||||
|
||||
public static int add_user(string user_name, bool system_account = false){
|
||||
string std_out, std_err;
|
||||
string cmd = "adduser%s --gecos '' --disabled-login %s".printf((system_account ? " --system" : ""), user_name);
|
||||
log_debug(cmd);
|
||||
int status = exec_sync(cmd, out std_out, out std_err);
|
||||
if (status != 0){
|
||||
log_error(std_err);
|
||||
}
|
||||
else{
|
||||
//log_msg(std_out);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public int add(){
|
||||
return add_user(name, is_system);
|
||||
}
|
||||
|
||||
public void check_encrypted_dirs() {
|
||||
|
||||
// check encrypted home ------------------------------
|
||||
@ -312,96 +284,5 @@ public class SystemUser : GLib.Object {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public bool update_passwd_file(){
|
||||
|
||||
string file_path = "/etc/passwd";
|
||||
string txt = file_read(file_path);
|
||||
|
||||
var txt_new = "";
|
||||
foreach(string line in txt.split("\n")){
|
||||
if (line.strip().length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string[] parts = line.split(":");
|
||||
|
||||
if (parts.length != 7){
|
||||
log_error("'passwd' file contains a record with non-standard fields" + ": %d".printf(parts.length));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parts[0].strip() == name){
|
||||
txt_new += get_passwd_line() + "\n";
|
||||
}
|
||||
else{
|
||||
txt_new += line + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
file_write(file_path, txt_new);
|
||||
|
||||
log_msg("Updated user settings in /etc/passwd" + ": %s".printf(name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string get_passwd_line(){
|
||||
string txt = "";
|
||||
txt += "%s".printf(name);
|
||||
txt += ":%s".printf(password);
|
||||
txt += ":%d".printf(uid);
|
||||
txt += ":%d".printf(gid);
|
||||
txt += ":%s".printf(user_info);
|
||||
txt += ":%s".printf(home_path);
|
||||
txt += ":%s".printf(shell_path);
|
||||
return txt;
|
||||
}
|
||||
|
||||
public bool update_shadow_file(){
|
||||
string file_path = "/etc/shadow";
|
||||
string txt = file_read(file_path);
|
||||
|
||||
var txt_new = "";
|
||||
foreach(string line in txt.split("\n")){
|
||||
if (line.strip().length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string[] parts = line.split(":");
|
||||
|
||||
if (parts.length != 9){
|
||||
log_error("'shadow' file contains a record with non-standard fields" + ": %d".printf(parts.length));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parts[0].strip() == name){
|
||||
txt_new += get_shadow_line() + "\n";
|
||||
}
|
||||
else{
|
||||
txt_new += line + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
file_write(file_path, txt_new);
|
||||
|
||||
log_msg("Updated user settings in /etc/shadow" + ": %s".printf(name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string get_shadow_line(){
|
||||
string txt = "";
|
||||
txt += "%s".printf(name);
|
||||
txt += ":%s".printf(pwd_hash);
|
||||
txt += ":%s".printf(pwd_last_changed);
|
||||
txt += ":%s".printf(pwd_age_min);
|
||||
txt += ":%s".printf(pwd_age_max);
|
||||
txt += ":%s".printf(pwd_warning_period);
|
||||
txt += ":%s".printf(pwd_inactivity_period);
|
||||
txt += ":%s".printf(pwd_expiraton_date);
|
||||
txt += ":%s".printf(reserved_field);
|
||||
return txt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,28 +102,6 @@ namespace TeeJee.FileSystem{
|
||||
}
|
||||
}
|
||||
|
||||
public bool file_move_to_trash(string file_path){
|
||||
|
||||
/* Check and delete file */
|
||||
|
||||
var file = File.new_for_path (file_path);
|
||||
if (file.query_exists ()) {
|
||||
Posix.system("gvfs-trash '%s'".printf(escape_single_quote(file_path)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool file_shred(string file_path){
|
||||
|
||||
/* Check and delete file */
|
||||
|
||||
var file = File.new_for_path (file_path);
|
||||
if (file.query_exists ()) {
|
||||
Posix.system("shred -u '%s'".printf(escape_single_quote(file_path)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int64 file_line_count (string file_path){
|
||||
/* Count number of lines in text file */
|
||||
string cmd = "wc -l '%s'".printf(escape_single_quote(file_path));
|
||||
@ -397,10 +375,6 @@ namespace TeeJee.FileSystem{
|
||||
return (status == 0);
|
||||
}
|
||||
|
||||
public bool dir_move_to_trash (string dir_path){
|
||||
return file_move_to_trash(dir_path);
|
||||
}
|
||||
|
||||
public bool dir_is_empty (string dir_path){
|
||||
|
||||
/* Check if directory is empty */
|
||||
@ -425,6 +399,7 @@ namespace TeeJee.FileSystem{
|
||||
}
|
||||
|
||||
public bool filesystem_supports_hardlinks(string path, out bool is_readonly){
|
||||
|
||||
bool supports_hardlinks = false;
|
||||
is_readonly = false;
|
||||
|
||||
@ -469,6 +444,7 @@ namespace TeeJee.FileSystem{
|
||||
}
|
||||
|
||||
public Gee.ArrayList<string> dir_list_names(string path){
|
||||
|
||||
var list = new Gee.ArrayList<string>();
|
||||
|
||||
try
|
||||
@ -494,69 +470,6 @@ namespace TeeJee.FileSystem{
|
||||
return list;
|
||||
}
|
||||
|
||||
public bool dir_tar (string src_dir, string tar_file, bool recursion = true){
|
||||
if (dir_exists(src_dir)) {
|
||||
|
||||
if (file_exists(tar_file)){
|
||||
file_delete(tar_file);
|
||||
}
|
||||
|
||||
var src_parent = file_parent(src_dir);
|
||||
var src_name = file_basename(src_dir);
|
||||
|
||||
string cmd = "tar cvf '%s' --overwrite --%srecursion -C '%s' '%s'\n".printf(
|
||||
escape_single_quote(tar_file),
|
||||
(recursion ? "" : "no-"),
|
||||
escape_single_quote(src_parent),
|
||||
escape_single_quote(src_name));
|
||||
|
||||
log_debug(cmd);
|
||||
|
||||
string stdout, stderr;
|
||||
int status = exec_script_sync(cmd, out stdout, out stderr);
|
||||
if (status == 0){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
log_msg(stderr);
|
||||
}
|
||||
}
|
||||
else{
|
||||
log_error(_("Dir not found") + ": %s".printf(src_dir));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool dir_untar (string tar_file, string dst_dir){
|
||||
if (file_exists(tar_file)) {
|
||||
|
||||
if (!dir_exists(dst_dir)){
|
||||
dir_create(dst_dir);
|
||||
}
|
||||
|
||||
string cmd = "tar xvf '%s' --overwrite --same-permissions -C '%s'\n".printf(
|
||||
escape_single_quote(tar_file),
|
||||
escape_single_quote(dst_dir));
|
||||
|
||||
log_debug(cmd);
|
||||
|
||||
string stdout, stderr;
|
||||
int status = exec_script_sync(cmd, out stdout, out stderr);
|
||||
if (status == 0){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
log_msg(stderr);
|
||||
}
|
||||
}
|
||||
else{
|
||||
log_error(_("File not found") + ": %s".printf(tar_file));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool chown(string dir_path, string user, string group = user){
|
||||
string cmd = "chown %s:%s -R '%s'".printf(user, group, escape_single_quote(dir_path));
|
||||
int status = exec_sync(cmd, null, null);
|
||||
@ -599,154 +512,6 @@ namespace TeeJee.FileSystem{
|
||||
return (long)(dir_size(path) / 1024.0);
|
||||
}
|
||||
|
||||
// archiving and encryption ----------------
|
||||
|
||||
// dep: tar gzip gpg
|
||||
public bool file_tar_encrypt (string src_file, string dst_file, string password){
|
||||
if (file_exists(src_file)) {
|
||||
if (file_exists(dst_file)){
|
||||
file_delete(dst_file);
|
||||
}
|
||||
|
||||
var src_dir = file_parent(src_file);
|
||||
var src_name = file_basename(src_file);
|
||||
|
||||
var dst_dir = file_parent(dst_file);
|
||||
var dst_name = file_basename(dst_file);
|
||||
var tar_name = dst_name[0 : dst_name.index_of(".gpg")];
|
||||
var tar_file = "%s/%s".printf(dst_dir, tar_name);
|
||||
|
||||
string cmd = "tar cvf '%s' --overwrite -C '%s' '%s'\n".printf(
|
||||
escape_single_quote(tar_file),
|
||||
escape_single_quote(src_dir),
|
||||
escape_single_quote(src_name));
|
||||
|
||||
cmd += "gpg --passphrase '%s' -o '%s' --symmetric '%s'\n".printf(
|
||||
password,
|
||||
escape_single_quote(dst_file),
|
||||
escape_single_quote(tar_file));
|
||||
|
||||
cmd += "rm -f '%s'\n".printf(escape_single_quote(tar_file));
|
||||
|
||||
log_debug(cmd);
|
||||
|
||||
string stdout, stderr;
|
||||
int status = exec_script_sync(cmd, out stdout, out stderr);
|
||||
if (status == 0){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
log_msg(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// dep: tar gzip gpg
|
||||
public string file_decrypt_untar_read (string src_file, string password){
|
||||
|
||||
if (file_exists(src_file)) {
|
||||
|
||||
//var src_name = file_basename(src_file);
|
||||
//var tar_name = src_name[0 : src_name.index_of(".gpg")];
|
||||
//var tar_file = "%s/%s".printf(TEMP_DIR, tar_name);
|
||||
//var temp_file = "%s/%s".printf(TEMP_DIR, random_string());
|
||||
|
||||
string cmd = "";
|
||||
|
||||
cmd += "gpg --quiet --no-verbose --passphrase '%s' -o- --decrypt '%s'".printf(
|
||||
password,
|
||||
escape_single_quote(src_file));
|
||||
|
||||
cmd += " | tar xf - --to-stdout 2>/dev/null\n";
|
||||
cmd += "exit $?\n";
|
||||
|
||||
log_debug(cmd);
|
||||
|
||||
string std_out, std_err;
|
||||
int status = exec_script_sync(cmd, out std_out, out std_err);
|
||||
if (status == 0){
|
||||
return std_out;
|
||||
}
|
||||
else{
|
||||
log_error(std_err);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
else{
|
||||
log_error(_("File is missing") + ": %s".printf(src_file));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// dep: tar gzip gpg
|
||||
public bool decrypt_and_untar (string src_file, string dst_file, string password){
|
||||
if (file_exists(src_file)) {
|
||||
if (file_exists(dst_file)){
|
||||
file_delete(dst_file);
|
||||
}
|
||||
|
||||
var src_dir = file_parent(src_file);
|
||||
var src_name = file_basename(src_file);
|
||||
var tar_name = src_name[0 : src_name.index_of(".gpg")];
|
||||
var tar_file = "%s/%s".printf(src_dir, tar_name);
|
||||
|
||||
string cmd = "";
|
||||
|
||||
// gpg cannot overwrite - remove tar file if it exists
|
||||
cmd += "rm -f '%s'\n".printf(escape_single_quote(tar_file));
|
||||
|
||||
cmd += "gpg --passphrase '%s' -o '%s' --decrypt '%s'\n".printf(
|
||||
password,
|
||||
escape_single_quote(tar_file),
|
||||
escape_single_quote(src_file));
|
||||
|
||||
cmd += "status=$?; if [ $status -ne 0 ]; then exit $status; fi\n";
|
||||
|
||||
cmd += "tar xvf '%s' --overwrite --same-permissions -C '%s'\n".printf(
|
||||
escape_single_quote(tar_file),
|
||||
escape_single_quote(file_parent(dst_file)));
|
||||
|
||||
cmd += "rm -f '%s'\n".printf(escape_single_quote(tar_file));
|
||||
|
||||
log_debug(cmd);
|
||||
|
||||
string stdout, stderr;
|
||||
int status = exec_script_sync(cmd, out stdout, out stderr);
|
||||
if (status == 0){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
log_error(stderr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
log_error(_("File is missing") + ": %s".printf(src_file));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// hashing -----------
|
||||
|
||||
private string hash_md5(string path){
|
||||
Checksum checksum = new Checksum (ChecksumType.MD5);
|
||||
FileStream stream = FileStream.open (path, "rb");
|
||||
|
||||
uint8 fbuf[100];
|
||||
size_t size;
|
||||
while ((size = stream.read (fbuf)) > 0){
|
||||
checksum.update (fbuf, size);
|
||||
}
|
||||
|
||||
unowned string digest = checksum.get_string();
|
||||
|
||||
return digest;
|
||||
}
|
||||
|
||||
// misc --------------------
|
||||
|
||||
public string format_file_size (
|
||||
@ -799,44 +564,17 @@ namespace TeeJee.FileSystem{
|
||||
}
|
||||
|
||||
public string escape_single_quote(string file_path){
|
||||
|
||||
return file_path.replace("'","'\\''");
|
||||
}
|
||||
|
||||
|
||||
// dep: chmod
|
||||
public int chmod (string file, string permission){
|
||||
|
||||
/* Change file permissions */
|
||||
string cmd = "chmod %s '%s'".printf(permission, escape_single_quote(file));
|
||||
return exec_sync (cmd, null, null);
|
||||
}
|
||||
|
||||
// dep: realpath
|
||||
public string resolve_relative_path (string filePath){
|
||||
|
||||
/* Resolve the full path of given file using 'realpath' command */
|
||||
|
||||
string filePath2 = filePath;
|
||||
if (filePath2.has_prefix ("~")){
|
||||
filePath2 = Environment.get_home_dir () + "/" + filePath2[2:filePath2.length];
|
||||
}
|
||||
|
||||
try {
|
||||
string output = "";
|
||||
string cmd = "realpath '%s'".printf(escape_single_quote(filePath2));
|
||||
Process.spawn_command_line_sync(cmd, out output);
|
||||
output = output.strip ();
|
||||
if (FileUtils.test(output, GLib.FileTest.EXISTS)){
|
||||
return output;
|
||||
}
|
||||
}
|
||||
catch(Error e){
|
||||
log_error (e.message);
|
||||
}
|
||||
|
||||
return filePath2;
|
||||
}
|
||||
|
||||
public int rsync(string sourceDirectory, string destDirectory, bool updateExisting, bool deleteExtra){
|
||||
|
||||
/* Sync files with rsync */
|
||||
|
@ -31,53 +31,6 @@ namespace TeeJee.Misc {
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.ProcessHelper;
|
||||
|
||||
// color format -------------------
|
||||
|
||||
public static Gdk.RGBA hex_to_rgba (string hex_color){
|
||||
|
||||
/* Converts the color in hex to RGBA */
|
||||
|
||||
string hex = hex_color.strip().down();
|
||||
if (hex.has_prefix("#") == false){
|
||||
hex = "#" + hex;
|
||||
}
|
||||
|
||||
Gdk.RGBA color = Gdk.RGBA();
|
||||
if(color.parse(hex) == false){
|
||||
color.parse("#000000");
|
||||
}
|
||||
color.alpha = 255;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
public static string rgba_to_hex (Gdk.RGBA color, bool alpha = false, bool prefix_hash = true){
|
||||
|
||||
/* Converts the color in RGBA to hex */
|
||||
|
||||
string hex = "";
|
||||
|
||||
if (alpha){
|
||||
hex = "%02x%02x%02x%02x".printf((uint)(Math.round(color.red*255)),
|
||||
(uint)(Math.round(color.green*255)),
|
||||
(uint)(Math.round(color.blue*255)),
|
||||
(uint)(Math.round(color.alpha*255)))
|
||||
.up();
|
||||
}
|
||||
else {
|
||||
hex = "%02x%02x%02x".printf((uint)(Math.round(color.red*255)),
|
||||
(uint)(Math.round(color.green*255)),
|
||||
(uint)(Math.round(color.blue*255)))
|
||||
.up();
|
||||
}
|
||||
|
||||
if (prefix_hash){
|
||||
hex = "#" + hex;
|
||||
}
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
// localization --------------------
|
||||
|
||||
public void set_numeric_locale(string type){
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
namespace TeeJee.ProcessHelper{
|
||||
|
||||
using TeeJee.Logging;
|
||||
using TeeJee.FileSystem;
|
||||
using TeeJee.Misc;
|
||||
@ -342,35 +343,6 @@ namespace TeeJee.ProcessHelper{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void get_proc_io_stats(int pid, out int64 read_bytes, out int64 write_bytes){
|
||||
|
||||
/* Returns the number of bytes read and written by a process to disk */
|
||||
|
||||
string io_stat_file_path = "/proc/%d/io".printf(pid);
|
||||
var file = File.new_for_path(io_stat_file_path);
|
||||
|
||||
read_bytes = 0;
|
||||
write_bytes = 0;
|
||||
|
||||
try {
|
||||
if (file.query_exists()){
|
||||
var dis = new DataInputStream (file.read());
|
||||
string line;
|
||||
while ((line = dis.read_line (null)) != null) {
|
||||
if(line.has_prefix("rchar:")){
|
||||
read_bytes = int64.parse(line.replace("rchar:","").strip());
|
||||
}
|
||||
else if(line.has_prefix("wchar:")){
|
||||
write_bytes = int64.parse(line.replace("wchar:","").strip());
|
||||
}
|
||||
}
|
||||
} //stream closed
|
||||
}
|
||||
catch(Error e){
|
||||
log_error (e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// dep: ps TODO: Rewrite using /proc
|
||||
public bool process_is_running(long pid){
|
||||
|
||||
|
@ -151,7 +151,6 @@ namespace TeeJee.System{
|
||||
return get_user_home(get_username_effective());
|
||||
}
|
||||
|
||||
|
||||
// application -----------------------------------------------
|
||||
|
||||
public string get_app_path(){
|
||||
@ -286,45 +285,6 @@ namespace TeeJee.System{
|
||||
|
||||
// internet helpers ----------------------
|
||||
|
||||
public bool check_internet_connectivity(){
|
||||
bool connected = false;
|
||||
connected = check_internet_connectivity_test1();
|
||||
|
||||
if (connected){
|
||||
return connected;
|
||||
}
|
||||
|
||||
if (!connected){
|
||||
connected = check_internet_connectivity_test2();
|
||||
}
|
||||
|
||||
return connected;
|
||||
}
|
||||
|
||||
public bool check_internet_connectivity_test1(){
|
||||
int exit_code = -1;
|
||||
string std_err;
|
||||
string std_out;
|
||||
|
||||
string cmd = "ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3`\n";
|
||||
cmd += "exit $?";
|
||||
exit_code = exec_script_sync(cmd, out std_out, out std_err, false);
|
||||
|
||||
return (exit_code == 0);
|
||||
}
|
||||
|
||||
public bool check_internet_connectivity_test2(){
|
||||
int exit_code = -1;
|
||||
string std_err;
|
||||
string std_out;
|
||||
|
||||
string cmd = "ping -q -w 1 -c 1 google.com\n";
|
||||
cmd += "exit $?";
|
||||
exit_code = exec_script_sync(cmd, out std_out, out std_err, false);
|
||||
|
||||
return (exit_code == 0);
|
||||
}
|
||||
|
||||
public bool shutdown (){
|
||||
|
||||
/* Shutdown the system immediately */
|
||||
@ -472,43 +432,6 @@ namespace TeeJee.System{
|
||||
return dir_exists("/sys/firmware/efi");
|
||||
}
|
||||
|
||||
public void open_terminal_window(
|
||||
string terminal_emulator,
|
||||
string working_dir,
|
||||
string script_file_to_execute,
|
||||
bool run_as_admin){
|
||||
|
||||
string cmd = "";
|
||||
if (run_as_admin){
|
||||
cmd += "pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY ";
|
||||
}
|
||||
|
||||
string term = terminal_emulator;
|
||||
if (!command_exists(term)){
|
||||
term = "gnome-terminal";
|
||||
if (!command_exists(term)){
|
||||
term = "xfce4-terminal";
|
||||
}
|
||||
}
|
||||
|
||||
cmd += term;
|
||||
|
||||
switch (term){
|
||||
case "gnome-terminal":
|
||||
case "xfce4-terminal":
|
||||
if (working_dir.length > 0){
|
||||
cmd += " --working-directory='%s'".printf(escape_single_quote(working_dir));
|
||||
}
|
||||
if (script_file_to_execute.length > 0){
|
||||
cmd += " -e '%s\n; echo Press ENTER to exit... ; read dummy;'".printf(escape_single_quote(script_file_to_execute));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
log_debug(cmd);
|
||||
exec_script_async(cmd);
|
||||
}
|
||||
|
||||
// timers --------------------------------------------------
|
||||
|
||||
public GLib.Timer timer_start(){
|
||||
@ -551,7 +474,6 @@ namespace TeeJee.System{
|
||||
log_msg("%s %lu\n".printf(seconds.to_string(), microseconds));
|
||||
}
|
||||
|
||||
|
||||
public void set_numeric_locale(string type){
|
||||
Intl.setlocale(GLib.LocaleCategory.NUMERIC, type);
|
||||
Intl.setlocale(GLib.LocaleCategory.COLLATE, type);
|
||||
|
12
src/makefile
12
src/makefile
@ -5,6 +5,7 @@ CHECKEXECS := $(foreach exec,$(EXECUTABLES), $(if $(shell which $(exec)),,$(erro
|
||||
|
||||
prefix=/usr
|
||||
sysconfdir=/etc
|
||||
appconfdir=$(sysconfdir)/timeshift
|
||||
bindir=$(prefix)/bin
|
||||
sharedir=$(prefix)/share
|
||||
polkitdir=$(sharedir)/polkit-1/actions
|
||||
@ -54,7 +55,7 @@ app-gtk:
|
||||
Core/*.vala Gtk/*.vala Utility/*.vala Utility/Gtk/*.vala \
|
||||
-o ${app_name}-gtk \
|
||||
--pkg glib-2.0 --pkg gio-unix-2.0 --pkg posix \
|
||||
--pkg gee-0.8 --pkg json-glib-1.0 \
|
||||
--pkg gee-0.8 --pkg json-glib-1.0 --pkg gio-2.0 \
|
||||
--pkg gtk+-3.0 --pkg vte-2.91 $(xapp_pkg)
|
||||
|
||||
app-console:
|
||||
@ -65,7 +66,7 @@ app-console:
|
||||
Core/*.vala Utility/*.vala Utility/Gtk/*.vala Console/*.vala \
|
||||
-o ${app_name} \
|
||||
--pkg glib-2.0 --pkg gio-unix-2.0 --pkg posix \
|
||||
--pkg gee-0.8 --pkg json-glib-1.0 \
|
||||
--pkg gee-0.8 --pkg json-glib-1.0 --pkg gio-2.0 \
|
||||
--pkg gtk+-3.0 --pkg vte-2.91 $(xapp_pkg)
|
||||
|
||||
manpage:
|
||||
@ -102,7 +103,8 @@ install:
|
||||
mkdir -p "$(DESTDIR)$(man1dir)"
|
||||
mkdir -p "$(DESTDIR)$(launcherdir)"
|
||||
mkdir -p "$(DESTDIR)$(polkitdir)"
|
||||
mkdir -p "$(DESTDIR)$(sysconfdir)/default"
|
||||
mkdir -p "$(DESTDIR)$(sysconfdir)"
|
||||
mkdir -p "$(DESTDIR)$(appconfdir)"
|
||||
mkdir -p "$(DESTDIR)$(sharedir)/${app_name}"
|
||||
mkdir -p "$(DESTDIR)$(sharedir)/icons"
|
||||
mkdir -p "$(DESTDIR)$(sharedir)/appdata"
|
||||
@ -126,7 +128,7 @@ install:
|
||||
install -m 0755 ${app_name}-gtk.desktop "$(DESTDIR)$(launcherdir)"
|
||||
|
||||
# config
|
||||
install -m 0644 ../files/${app_name}.json "$(DESTDIR)$(sysconfdir)/default"
|
||||
install -m 0644 ../files/${app_name}.json "$(DESTDIR)$(appconfdir)/default.json"
|
||||
|
||||
# man page
|
||||
install -m 0644 ../man/${app_name}.1.gz "$(DESTDIR)$(man1dir)/${app_name}.1.gz"
|
||||
@ -136,7 +138,7 @@ install:
|
||||
chmod --recursive 0644 $(DESTDIR)$(sharedir)/icons/hicolor/*/apps/${app_name}.png
|
||||
|
||||
# appdata
|
||||
install -m 0644 ../debian/${app_name}.appdata.xml "$(DESTDIR)$(sharedir)/appdata"
|
||||
#install -m 0644 ../debian/${app_name}.appdata.xml "$(DESTDIR)$(sharedir)/appdata"
|
||||
install -m 0644 ../debian/${app_name}.appdata.xml "$(DESTDIR)$(sharedir)/metainfo"
|
||||
|
||||
# translations
|
||||
|
@ -2,23 +2,23 @@
|
||||
|
||||
app_command='timeshift-gtk'
|
||||
|
||||
if [ `id -u` -eq 0 ]; then
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
# user is admin
|
||||
${app_command}
|
||||
else
|
||||
# user is not admin
|
||||
if `echo $- | grep "i" >/dev/null 2>&1`; then
|
||||
if echo $- | grep "i" >/dev/null 2>&1; then
|
||||
# script is running in interactive mode
|
||||
su - -c "${app_command}"
|
||||
else
|
||||
# script is running in non-interactive mode
|
||||
if [ $XDG_SESSION_TYPE = "wayland" ] ; then
|
||||
if [ "$XDG_SESSION_TYPE" = "wayland" ] ; then
|
||||
xhost +SI:localuser:root
|
||||
pkexec ${app_command}
|
||||
xhost -SI:localuser:root
|
||||
xhost
|
||||
elif command -v pkexec >/dev/null 2>&1; then
|
||||
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY ${app_command}
|
||||
pkexec ${app_command}
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
x-terminal-emulator -e "sudo ${app_command}"
|
||||
elif command -v su >/dev/null 2>&1; then
|
||||
|
1
timeshift-wiki
Submodule
1
timeshift-wiki
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit aa75c12bc38fc77a62d1002d7d442b4f102ab436
|
132
timeshift.geany
132
timeshift.geany
@ -1,132 +0,0 @@
|
||||
[indentation]
|
||||
indent_width=4
|
||||
indent_type=1
|
||||
indent_hard_tab_width=8
|
||||
detect_indent=false
|
||||
detect_indent_width=false
|
||||
indent_mode=2
|
||||
|
||||
[project]
|
||||
name=timeshift
|
||||
base_path=/home/teejee/projects/linux/timeshift
|
||||
description=
|
||||
file_patterns=
|
||||
|
||||
[long line marker]
|
||||
long_line_behaviour=1
|
||||
long_line_column=80
|
||||
|
||||
[files]
|
||||
current_page=44
|
||||
FILE_NAME_0=26;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FArchiveFile.vala;0;4
|
||||
FILE_NAME_1=24;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FAsyncTask.vala;0;4
|
||||
FILE_NAME_2=19;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FBash.vala;0;4
|
||||
FILE_NAME_3=22;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FCronTab.vala;0;4
|
||||
FILE_NAME_4=23;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FFileItem.vala;0;4
|
||||
FILE_NAME_5=25;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FLinuxDistro.vala;0;4
|
||||
FILE_NAME_6=25;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FOSDNotify.vala;0;4
|
||||
FILE_NAME_7=25;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FProcStats.vala;0;4
|
||||
FILE_NAME_8=7528;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FTeeJee.FileSystem.vala;0;4
|
||||
FILE_NAME_9=33;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FTeeJee.Json.vala;0;4
|
||||
FILE_NAME_10=30;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FTeeJee.Logging.vala;0;4
|
||||
FILE_NAME_11=1329;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FTeeJee.Misc.vala;0;4
|
||||
FILE_NAME_12=3234;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FTeeJee.Process.vala;0;4
|
||||
FILE_NAME_13=8888;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FTeeJee.System.vala;0;4
|
||||
FILE_NAME_14=2726;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FExcludeMessageWindow.vala;0;4
|
||||
FILE_NAME_15=2073;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FMainWindow.vala;0;4
|
||||
FILE_NAME_16=4051;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRestoreWindow.vala;0;4
|
||||
FILE_NAME_17=2406;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FSettingsWindow.vala;0;4
|
||||
FILE_NAME_18=24;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FRsyncTask.vala;0;4
|
||||
FILE_NAME_19=27;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FCore%2FAppExcludeEntry.vala;0;4
|
||||
FILE_NAME_20=8401;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FCore%2FSnapshot.vala;0;4
|
||||
FILE_NAME_21=5234;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FCore%2FSnapshotRepo.vala;0;4
|
||||
FILE_NAME_22=2001;Make;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2Fmakefile;0;4
|
||||
FILE_NAME_23=29;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRsyncLogWindow.vala;0;4
|
||||
FILE_NAME_24=3540;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FBackupBox.vala;0;4
|
||||
FILE_NAME_25=26;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FEstimateBox.vala;0;4
|
||||
FILE_NAME_26=10217;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FBackupDeviceBox.vala;0;4
|
||||
FILE_NAME_27=6002;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FExcludeBox.vala;0;4
|
||||
FILE_NAME_28=7388;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FScheduleBox.vala;0;4
|
||||
FILE_NAME_29=2532;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FFinishBox.vala;0;4
|
||||
FILE_NAME_30=4344;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FSetupWizardWindow.vala;0;4
|
||||
FILE_NAME_31=2801;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FBackupWindow.vala;0;4
|
||||
FILE_NAME_32=1011;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FSnapshotListBox.vala;0;4
|
||||
FILE_NAME_33=1402;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FDeleteWindow.vala;0;4
|
||||
FILE_NAME_34=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FDeleteBox.vala;0;4
|
||||
FILE_NAME_35=29;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FDeleteFileTask.vala;0;4
|
||||
FILE_NAME_36=2025;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRestoreBox.vala;0;4
|
||||
FILE_NAME_37=1972;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRestoreSummaryBox.vala;0;4
|
||||
FILE_NAME_38=4010;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRestoreDeviceBox.vala;0;4
|
||||
FILE_NAME_39=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRestoreExcludeBox.vala;0;4
|
||||
FILE_NAME_40=2324;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRestoreFinishBox.vala;0;4
|
||||
FILE_NAME_41=1712;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FExcludeAppsBox.vala;0;4
|
||||
FILE_NAME_42=39;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FExcludeListSummaryWindow.vala;0;4
|
||||
FILE_NAME_43=41629;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FDevice.vala;0;4
|
||||
FILE_NAME_44=438;None;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fdebian%2Fchangelog;0;4
|
||||
FILE_NAME_45=852;Conf;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fdebian%2Fcontrol;0;4
|
||||
FILE_NAME_46=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FAppLock.vala;0;4
|
||||
FILE_NAME_47=30;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FTimeoutCounter.vala;0;4
|
||||
FILE_NAME_48=1441;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FAppGtk.vala;0;4
|
||||
FILE_NAME_49=17372;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FConsole%2FAppConsole.vala;0;4
|
||||
FILE_NAME_50=3478;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FGtk%2FTerminalWindow.vala;0;4
|
||||
FILE_NAME_51=2742;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FCore%2FMain.vala;0;4
|
||||
FILE_NAME_52=992;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FBootOptionsWindow.vala;0;4
|
||||
FILE_NAME_53=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FBootOptionsBox.vala;0;4
|
||||
FILE_NAME_54=19269;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FGtkHelper.vala;0;4
|
||||
FILE_NAME_55=1669;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FCore%2FSubvolume.vala;0;4
|
||||
FILE_NAME_56=1074;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FDeleteFinishBox.vala;0;4
|
||||
FILE_NAME_57=3943;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FSnapshotBackendBox.vala;0;4
|
||||
FILE_NAME_58=10039;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FGtk%2FAboutWindow.vala;0;4
|
||||
FILE_NAME_59=34;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FGtk%2FCustomMessageDialog.vala;0;4
|
||||
FILE_NAME_60=2710;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FFsTabEntry.vala;0;4
|
||||
FILE_NAME_61=27;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FSystemGroup.vala;0;4
|
||||
FILE_NAME_62=895;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FSystemUser.vala;0;4
|
||||
FILE_NAME_63=7678;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FUsersBox.vala;0;4
|
||||
FILE_NAME_64=548;JSON;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Ffiles%2Ftimeshift.json;0;4
|
||||
FILE_NAME_65=697;Conf;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2Ftimeshift-gtk.desktop;0;4
|
||||
FILE_NAME_66=3473;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FGtk%2FDonationWindow.vala;0;4
|
||||
FILE_NAME_67=2818;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FIconManager.vala;0;4
|
||||
FILE_NAME_68=0;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FLicenseText.vala;0;4
|
||||
FILE_NAME_69=702;Sh;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fbuild-installers.sh;0;4
|
||||
FILE_NAME_70=11903;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FGtk%2FRsyncLogBox.vala;0;4
|
||||
FILE_NAME_71=46967;Po;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fpo%2Ftimeshift-sv.po;0;4
|
||||
FILE_NAME_72=1064;Sh;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fmerge-launchpad-translations.sh;0;4
|
||||
FILE_NAME_73=780;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2FUtility%2FMountEntry.vala;0;4
|
||||
FILE_NAME_74=279;None;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Frelease%2Fsanity.config;0;4
|
||||
FILE_NAME_75=528;Sh;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fsrc%2Ftimeshift-launcher;0;4
|
||||
FILE_NAME_76=120;Make;0;EUTF-8;1;1;1;%2Fhome%2Fteejee%2Fprojects%2Flinux%2Ftimeshift%2Fmakefile;0;4
|
||||
|
||||
[VTE]
|
||||
last_dir=/data/projects/linux/timeshift
|
||||
|
||||
[build-menu]
|
||||
ValaFT_00_LB=_Compile
|
||||
ValaFT_00_CM=
|
||||
ValaFT_00_WD=
|
||||
filetypes=Vala;Make;
|
||||
NF_00_LB=_Make
|
||||
NF_00_CM=make app-console app-gtk
|
||||
NF_00_WD=%p
|
||||
EX_00_LB=_Execute Debug
|
||||
EX_00_CM=pkexec timeshift-gtk
|
||||
EX_00_WD=%p/src
|
||||
EX_01_LB=Execute
|
||||
EX_01_CM=pkexec timeshift-gtk
|
||||
EX_01_WD=%p/src
|
||||
ValaFT_01_LB=_Build
|
||||
ValaFT_01_CM=make app-console app-gtk
|
||||
ValaFT_01_WD=%p
|
||||
MakeFT_00_LB=
|
||||
MakeFT_00_CM=make app-console app-gtk
|
||||
MakeFT_00_WD=%p
|
||||
|
||||
[file_prefs]
|
||||
final_new_line=true
|
||||
ensure_convert_new_lines=false
|
||||
strip_trailing_spaces=false
|
||||
replace_tabs=false
|
||||
|
||||
[editor]
|
||||
line_wrapping=true
|
||||
line_break_column=72
|
||||
auto_continue_multiline=true
|
672
timeshift.pot
672
timeshift.pot
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user