mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-27 06:15:45 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aec8ba4d12 |
@@ -1,3 +0,0 @@
|
||||
|
||||
# Make sure github recognizes header files as C++, not C.
|
||||
*.h linguist-language=C++
|
||||
@@ -1,171 +0,0 @@
|
||||
name: Build - 1.1 Branch (Tier 1 platforms)
|
||||
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the branch
|
||||
push:
|
||||
branches: [ release/1.1 ]
|
||||
pull_request:
|
||||
branches: [ release/1.1 ]
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
env:
|
||||
SMARTMONTOOLS_INSTALLER: smartmontools-7.2-1.win32-setup.exe
|
||||
SMARTMONTOOLS_URL: https://nav.dl.sourceforge.net/project/smartmontools/smartmontools/7.2/smartmontools-7.2-1.win32-setup.exe
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
linux-ubuntu:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: release/1.1
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get install libpcre3-dev libgtkmm-3.0-dev gettext autoconf automake
|
||||
|
||||
- name: Run Autogen
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/gsmartcontrol
|
||||
run: ./autogen.sh
|
||||
|
||||
- name: Create Build Directory
|
||||
shell: bash
|
||||
run: mkdir -p ${{runner.workspace}}/build
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: >
|
||||
$GITHUB_WORKSPACE/configure --prefix=/usr --enable-tests
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: make
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: make check
|
||||
|
||||
- name: Pack Source
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: make dist
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Source Packages (1.1 Branch)
|
||||
path: ${{runner.workspace}}/build/gsmartcontrol-*.tar.bz2
|
||||
|
||||
|
||||
windows-msys2:
|
||||
# Disable for now, as the configure stage errors out with "The directory name is invalid."
|
||||
if: ${{ false }}
|
||||
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include: [
|
||||
{ msystem: MINGW64, arch: x86_64, root: /mingw64 },
|
||||
{ msystem: MINGW32, arch: i686, root: /mingw32 }
|
||||
]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: release/1.1
|
||||
|
||||
- uses: msys2/setup-msys2@v2
|
||||
# p7zip is needed to extract smartmontools
|
||||
# fontconfig owns /etc/fonts
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
update: true
|
||||
install: >-
|
||||
mingw-w64-${{ matrix.arch }}-gtkmm3
|
||||
mingw-w64-${{ matrix.arch }}-pkg-config
|
||||
autoconf
|
||||
automake
|
||||
mingw-w64-${{ matrix.arch }}-gcc
|
||||
mingw-w64-${{ matrix.arch }}-fontconfig
|
||||
make
|
||||
p7zip
|
||||
|
||||
- name: Run Autogen
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/gsmartcontrol
|
||||
run: ./autogen.sh
|
||||
|
||||
- name: Create Build Directory
|
||||
shell: cmd
|
||||
working-directory: ${{runner.workspace}}
|
||||
run: md build
|
||||
|
||||
- name: Configure
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: ../gsmartcontrol/configure --enable-tests
|
||||
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: make
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: msys2 {0}
|
||||
run: make check
|
||||
|
||||
- name: Download Package Requirements
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: |
|
||||
mkdir smartmontools
|
||||
cd smartmontools
|
||||
wget $SMARTMONTOOLS_URL
|
||||
|
||||
- name: Extract Package Requirements (64-bit)
|
||||
if: ${{ matrix.msystem == 'MINGW64' }}
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/build/smartmontools
|
||||
run: >
|
||||
7z -bb1 e $SMARTMONTOOLS_INSTALLER
|
||||
bin64/smartctl.exe
|
||||
bin64/smartctl-nc.exe
|
||||
bin/update-smart-drivedb.exe
|
||||
bin/drivedb.h
|
||||
|
||||
- name: Extract Package Requirements (32-bit)
|
||||
if: ${{ matrix.msystem == 'MINGW32' }}
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/build/smartmontools
|
||||
run: >
|
||||
7z -bb1 e $SMARTMONTOOLS_INSTALLER
|
||||
bin/smartctl.exe
|
||||
bin/smartctl-nc.exe
|
||||
bin/update-smart-drivedb.exe
|
||||
bin/drivedb.h
|
||||
|
||||
- name: Package ZIP
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: make win-zip-dist
|
||||
|
||||
- name: Package NSIS
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: make win-dist
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Windows Packages (1.1 Branch)
|
||||
path: ${{runner.workspace}}/build/gsmartcontrol-*-win*.*
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
name: Build - 1.1 Branch (Tier 2 platforms)
|
||||
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the branch
|
||||
push:
|
||||
branches: [ release/1.1 ]
|
||||
pull_request:
|
||||
branches: [ release/1.1 ]
|
||||
# Allows you to run this workflow manually from the Actions tab.
|
||||
# This does not work for non-default branches, that's why we use the push / pull_request triggers above.
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
macos-homebrew:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: release/1.1
|
||||
|
||||
- name: Install Dependencies
|
||||
run: brew install pkg-config gtkmm3 pcre automake autoconf
|
||||
|
||||
- name: Run Autogen
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/gsmartcontrol
|
||||
run: ./autogen.sh
|
||||
|
||||
- name: Create Build Directory
|
||||
shell: bash
|
||||
run: mkdir -p ${{runner.workspace}}/build
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: >
|
||||
$GITHUB_WORKSPACE/configure --prefix=/usr --enable-tests
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: make
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
run: make check
|
||||
|
||||
|
||||
freebsd:
|
||||
# Disable for now, make cannot find file2csource.sh for some reason.
|
||||
if: ${{ false }} # disable for now
|
||||
|
||||
runs-on: macos-10.15
|
||||
# env:
|
||||
# variables to pass to VM
|
||||
# MYTOKEN : ${{ secrets.MYTOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: release/1.1
|
||||
|
||||
- name: Build and test in FreeBSD
|
||||
id: test
|
||||
uses: vmactions/freebsd-vm@v0.1.5
|
||||
with:
|
||||
usesh: true
|
||||
mem: 2048
|
||||
prepare: >
|
||||
pkg install -y pkgconf gtkmm30 gettext pcre libiconv autoconf automake
|
||||
|
||||
run: >
|
||||
./autogen.sh
|
||||
|
||||
mkdir build && cd build
|
||||
|
||||
../configure --prefix=/usr --enable-tests
|
||||
|
||||
make
|
||||
|
||||
make check
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
|
||||
# Builds
|
||||
/0*
|
||||
/doxygen_doc*
|
||||
/win32*
|
||||
/win64*
|
||||
/cmake-build-*
|
||||
|
||||
# Build system artifacts
|
||||
/autom4te.cache
|
||||
/aclocal.m4
|
||||
/ar-lib
|
||||
/compilation_flags
|
||||
/compile
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.log
|
||||
/config.status
|
||||
/config.sub
|
||||
/configure
|
||||
/depcomp
|
||||
/gsmartcontrol.spec
|
||||
/install-sh
|
||||
Makefile
|
||||
Makefile.in
|
||||
/missing
|
||||
/stamp-h1
|
||||
/version.txt
|
||||
*.glade.cpp
|
||||
*.ui.cpp
|
||||
*.txt.cpp
|
||||
/data/gsmartcontrol.appdata.xml
|
||||
/data/gsmartcontrol.desktop
|
||||
/data/gsmartcontrol-root
|
||||
/data/nsis/distribution.txt
|
||||
/data/nsis/gsmartcontrol.nsi
|
||||
/debian.dist/changelog
|
||||
/src/gsc_winres.rc
|
||||
/src/gsmartcontrol.exe.manifest
|
||||
.deps
|
||||
|
||||
|
||||
# Non-project files
|
||||
/TODO
|
||||
|
||||
# Doxygen generated
|
||||
/doxygen_doc
|
||||
|
||||
# OS-generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
Icon?
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# IDE
|
||||
/.vs
|
||||
/*.pcs
|
||||
/.idea
|
||||
/CMakeLists.txt.user
|
||||
/.kdev4
|
||||
|
||||
# Translations
|
||||
/po/boldquot.sed
|
||||
/po/en@boldquot.header
|
||||
/po/en@quot.header
|
||||
/po/insert-header.sin
|
||||
/po/Makevars.template
|
||||
/po/quot.sed
|
||||
/po/remove-potcdate.sin
|
||||
/po/Rules-quot
|
||||
/po/gsmartcontrol.pot
|
||||
/po/*.gmo
|
||||
|
||||
# Backup files
|
||||
*~
|
||||
@@ -0,0 +1,18 @@
|
||||
0*
|
||||
*.pcs
|
||||
autom4te.cache
|
||||
Makefile.in
|
||||
configure
|
||||
depcomp
|
||||
config.guess
|
||||
config.sub
|
||||
aclocal.m4
|
||||
config.h.in
|
||||
compile
|
||||
ar-lib
|
||||
missing
|
||||
install-sh
|
||||
*.glade.cpp
|
||||
*.ui.cpp
|
||||
*.txt.cpp
|
||||
.kdev4
|
||||
@@ -0,0 +1 @@
|
||||
svn propset svn:ignore -F .svnignore.txt .
|
||||
+58
-104
@@ -6,7 +6,7 @@ SUBDIRS = data debian.dist src
|
||||
|
||||
|
||||
# These files are actually needed for compilation.
|
||||
noinst_DATA = AUTHORS.txt LICENSE_gsmartcontrol.txt
|
||||
noinst_DATA = AUTHORS.txt LICENSE_gsmartcontrol.txt README.txt
|
||||
|
||||
|
||||
# For the files to be bundled with the distribution, specify them in
|
||||
@@ -71,8 +71,7 @@ win-dist-clean: win-dist-cleanup
|
||||
win-dist-prepare-all: nsis-dist-prepare win-zip-dist-prepare
|
||||
|
||||
|
||||
# All of GTK+.
|
||||
# This includes both MSYS and OpenSUSE/mingw patterns.
|
||||
# All of GTK+
|
||||
GTK_BIN_FILES = gdk-pixbuf-query-loaders.exe \
|
||||
gspawn-win32-helper-console.exe \
|
||||
gspawn-win32-helper.exe \
|
||||
@@ -82,18 +81,14 @@ GTK_BIN_FILES = gdk-pixbuf-query-loaders.exe \
|
||||
gtk-update-icon-cache-3.0.exe \
|
||||
libatk-1.*.dll \
|
||||
libatkmm-1.*.dll \
|
||||
libbrotlidec.dll \
|
||||
libbrotlicommon.dll \
|
||||
libbz2-*.dll \
|
||||
libcairo-*.dll \
|
||||
libcairomm-1*.dll \
|
||||
libdatrie-*.dll \
|
||||
libepoxy-*.dll \
|
||||
libffi-*.dll \
|
||||
libexpat-*.dll \
|
||||
libfontconfig-*.dll \
|
||||
libfreetype-*.dll \
|
||||
libfribidi-*.dll \
|
||||
libgdk-3*.dll \
|
||||
libgdk_pixbuf-2.*.dll \
|
||||
libgdkmm-3.*.dll \
|
||||
@@ -108,7 +103,7 @@ GTK_BIN_FILES = gdk-pixbuf-query-loaders.exe \
|
||||
libgtk-3*.dll \
|
||||
libgtkmm-3*.dll \
|
||||
libharfbuzz*.dll \
|
||||
libiconv-*.dll \
|
||||
libiconv*.dll \
|
||||
libintl*.dll \
|
||||
libjasper*.dll \
|
||||
libjpeg*.dll \
|
||||
@@ -117,14 +112,11 @@ GTK_BIN_FILES = gdk-pixbuf-query-loaders.exe \
|
||||
libpixman*.dll \
|
||||
libpng16-*.dll \
|
||||
libsigc-2.*.dll \
|
||||
libssp-*.dll \
|
||||
libstdc++-*.dll \
|
||||
libthai-*.dll \
|
||||
libtiff-*.dll \
|
||||
libwinpthread-*.dll \
|
||||
libxml2-*.dll \
|
||||
zlib1.dll \
|
||||
libz.dll
|
||||
zlib1.dll
|
||||
|
||||
|
||||
# Don't strip smartctl (it will only change the header), and
|
||||
@@ -138,9 +130,7 @@ win-dist-prepare: all
|
||||
cp $(top_srcdir)/AUTHORS.txt $(top_srcdir)/LICENSE_* $(top_srcdir)/README.txt win-dist/doc/
|
||||
cp $(top_srcdir)/NEWS win-dist/doc/NEWS.txt
|
||||
|
||||
# The manifest is already embedded in exe
|
||||
# cp src/gsmartcontrol.exe src/gsmartcontrol.exe.manifest win-dist/
|
||||
cp src/gsmartcontrol.exe win-dist/
|
||||
cp src/gsmartcontrol.exe src/gsmartcontrol.exe.manifest win-dist/
|
||||
|
||||
unix2dos win-dist/doc/*.txt
|
||||
|
||||
@@ -151,18 +141,11 @@ win-dist-prepare: all
|
||||
|
||||
for file in $(GTK_BIN_FILES); do for f in "@WINDOWS_SYSROOT@/bin/"$$file; do if test -f "$${f}"; then cp -p "$${f}" win-dist/; fi; done; done
|
||||
|
||||
# <prefix>/etc/gtk-3.0/ should contain settings.ini with a win32 theme.
|
||||
# <prefix>/etc should contain gtk-3.0/settings.ini
|
||||
$(MKDIR_P) win-dist/etc
|
||||
$(MKDIR_P) win-dist/etc/fonts
|
||||
$(MKDIR_P) win-dist/etc/gtk-3.0
|
||||
cp -p "@WINDOWS_SYSROOT@"/etc/fonts/fonts.conf win-dist/etc/fonts/
|
||||
# cp -p "@WINDOWS_SYSROOT@"/etc/gtk-3.0/im-multipress.conf win-dist/etc/gtk-3.0/
|
||||
# cp -p "@WINDOWS_SYSROOT@"/etc/gtk-3.0/settings.ini win-dist/etc/gtk-3.0/
|
||||
|
||||
# Without loaders, images and native file dialog do not work.
|
||||
$(MKDIR_P) win-dist/lib
|
||||
$(MKDIR_P) win-dist/lib/gdk-pixbuf-2.0
|
||||
cp -p -r "@WINDOWS_SYSROOT@"/lib/gdk-pixbuf-2.0/2.10.0 win-dist/lib/gdk-pixbuf-2.0
|
||||
cp -p "@WINDOWS_SYSROOT@"/etc/fonts/fonts.conf win-dist/etc/fonts
|
||||
cp -p -r "@WINDOWS_SYSROOT@"/etc/gtk-3.0 win-dist/etc
|
||||
|
||||
$(MKDIR_P) win-dist/share
|
||||
cp -p -r "@WINDOWS_SYSROOT@"/share/themes win-dist/share
|
||||
@@ -174,93 +157,66 @@ win-dist-prepare: all
|
||||
# $(MKDIR_P) win-dist/share/icons
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/hicolor win-dist/share/icons
|
||||
|
||||
# Needed for window titlebar (if using client-side decorations),
|
||||
# needed for window titlebar (if using client-side decorations),
|
||||
# tree sorting indicators, GUI icons.
|
||||
# Note that the current Adwaita uses "ui" directory, while win32 theme expects "actions".
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/index.theme win-dist/share/icons/Adwaita
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/ui/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/ui/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/ui/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/ui/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/ui/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/ui/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/actions/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/actions/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/actions/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/actions/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/actions/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/actions/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/actions
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/16x16/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/16x16/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/16x16/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/devices/drive-harddisk.png win-dist/share/icons/Adwaita/16x16/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/devices/media-optical.png win-dist/share/icons/Adwaita/16x16/devices
|
||||
# $(MKDIR_P) win-dist/share/icons/Adwaita/22x22/status
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/22x22/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/22x22/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/16x16/status/dialog-information.png win-dist/share/icons/Adwaita/16x16/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/22x22/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/22x22/status/dialog-information.png win-dist/share/icons/Adwaita/22x22/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/ui/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/ui/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/ui/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/ui/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/ui/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/ui/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/24x24/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/devices/drive-harddisk.png win-dist/share/icons/Adwaita/24x24/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/devices/media-optical.png win-dist/share/icons/Adwaita/24x24/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/actions/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/actions/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/actions/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/actions/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/actions/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/actions/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/actions
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/24x24/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/24x24/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/24x24/status/dialog-information.png win-dist/share/icons/Adwaita/24x24/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/ui/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/ui/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/ui/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/ui/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/ui/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/ui/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/32x32/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/devices/drive-harddisk.png win-dist/share/icons/Adwaita/32x32/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/devices/media-optical.png win-dist/share/icons/Adwaita/32x32/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/actions/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/actions/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/actions/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/actions/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/actions/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/actions/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/actions
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/32x32/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/32x32/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/32x32/status/dialog-information.png win-dist/share/icons/Adwaita/32x32/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/ui/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/ui/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/ui/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/ui/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/ui/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/ui/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/48x48/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/devices/drive-harddisk.png win-dist/share/icons/Adwaita/48x48/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/devices/media-optical.png win-dist/share/icons/Adwaita/48x48/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/actions/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/actions/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/actions/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/actions/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/actions/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/actions/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/actions
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/48x48/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/48x48/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/48x48/status/dialog-information.png win-dist/share/icons/Adwaita/48x48/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/ui/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/ui/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/ui/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/ui/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/ui/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/ui/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
# $(MKDIR_P) win-dist/share/icons/Adwaita/64x64/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/devices/drive-harddisk.png win-dist/share/icons/Adwaita/64x64/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/devices/media-optical.png win-dist/share/icons/Adwaita/64x64/devices
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/64x64/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/status
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/actions/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/actions/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/actions/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/actions/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/actions/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/actions/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/64x64/actions
|
||||
# $(MKDIR_P) win-dist/share/icons/Adwaita/64x64/status
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/64x64/status/dialog-information.png win-dist/share/icons/Adwaita/64x64/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/ui/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/ui/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/ui/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/ui/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/ui/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/ui/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
# $(MKDIR_P) win-dist/share/icons/Adwaita/96x96/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/devices/drive-harddisk.png win-dist/share/icons/Adwaita/96x96/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/devices/media-optical.png win-dist/share/icons/Adwaita/96x96/devices
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/96x96/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/status
|
||||
# $(MKDIR_P) win-dist/share/icons/Adwaita/256x256/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/256x256/devices/drive-harddisk.png win-dist/share/icons/Adwaita/256x256/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/256x256/devices/media-optical.png win-dist/share/icons/Adwaita/256x256/devices
|
||||
# $(MKDIR_P) win-dist/share/icons/Adwaita/256x256/status
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/256x256/status/dialog-information-symbolic.symbolic.png win-dist/share/icons/Adwaita/256x256/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/512x512/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/512x512/devices/drive-harddisk.png win-dist/share/icons/Adwaita/512x512/devices
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/512x512/devices/media-optical.png win-dist/share/icons/Adwaita/512x512/devices
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/actions/window-close-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/actions/window-maximize-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/actions/window-minimize-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/actions/window-restore-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/actions/pan-down-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/actions/pan-up-symbolic.symbolic.png win-dist/share/icons/Adwaita/96x96/actions
|
||||
# $(MKDIR_P) win-dist/share/icons/Adwaita/96x96/status
|
||||
# cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/96x96/status/dialog-information.png win-dist/share/icons/Adwaita/96x96/status
|
||||
$(MKDIR_P) win-dist/share/icons/Adwaita/256x256/status
|
||||
cp -p "@WINDOWS_SYSROOT@"/share/icons/Adwaita/256x256/status/dialog-information.png win-dist/share/icons/Adwaita/256x256/status
|
||||
|
||||
# other
|
||||
cp -p "@WINDOWS_SYSROOT@"/bin/libgcc_s_*.dll win-dist/
|
||||
@@ -288,9 +244,7 @@ win-zip-dist-prepare: win-dist-prepare
|
||||
cp -a win-dist $(WIN_ZIP_NAME)
|
||||
|
||||
win-zip-dist-nocleanup: win-zip-dist-prepare
|
||||
zip -9r $(WIN_ZIP_NAME).zip $(WIN_ZIP_NAME)
|
||||
# Only when cross-compiling:
|
||||
# zip -K -9r $(WIN_ZIP_NAME).zip $(WIN_ZIP_NAME)
|
||||
zip -K -9r $(WIN_ZIP_NAME).zip $(WIN_ZIP_NAME)
|
||||
|
||||
win-zip-dist-cleanup:
|
||||
rm -rf $(WIN_ZIP_NAME)
|
||||
|
||||
@@ -1,40 +1,3 @@
|
||||
Version 1.1.4, released on 2022-02-04
|
||||
Fixed a crash when trying to render main window icons which have incomplete
|
||||
data; this fixes a rare crash when scanning devices (#13).
|
||||
Fixed rendering compatibility issues with newer GTK3 versions.
|
||||
Fixed build system conflict with C++20 version header (#14).
|
||||
Fixed "Running command ..." dialog floating above windows of other
|
||||
applications (#17).
|
||||
Fixed a crash when system locale is set to invalid locale.
|
||||
Support Finnish decimal separator (backported from the Debian package)
|
||||
(#23).
|
||||
Set LC_NUMERIC=C for smartctl process to avoid locale-dependent number
|
||||
formatting (#23).
|
||||
Fixed printing all GTK messages as warnings; the messages are sorted by
|
||||
severity now.
|
||||
Add current time to default filename in Save Output dialog.
|
||||
Support macos stat command in file2csource.sh.
|
||||
Fixed a few typos (backported from the Debian package).
|
||||
Windows port now uses Adwaita theme due to issues with win32 theme.
|
||||
Windows port is dpi-aware now.
|
||||
|
||||
Version 1.1.3, released on 2017-11-12
|
||||
Fixed gsmartcontrol-root not launching if GDK_* variables are not set.
|
||||
|
||||
Version 1.1.2, released on 2017-11-11
|
||||
Fixed gsmartcontrol-root not passing GDK_SCALE and GDK_DPI_SCALE variables
|
||||
to gsmartcontrol when using PolKit.
|
||||
Fixed blurriness of icons in the main window with GDK_SCALE=2.
|
||||
Tweaked the main window interface.
|
||||
Windows: Show volume labels beside drive letters in icon tooltips.
|
||||
|
||||
Version 1.1.1, released on 2017-09-25
|
||||
Windows: Use Adwaita GTK+ theme for systems which support Classic Windows
|
||||
theme, since the default win32 GTK+ theme is broken in it; this
|
||||
includes Windows 7 and Windows Server.
|
||||
Statistics entry values are formatted with commas for readability.
|
||||
Moved help information to website.
|
||||
|
||||
Version 1.1.0, released on 2017-09-07
|
||||
New Statistics, Temperature Log, Error Recovery, Physical and Directory
|
||||
tabs.
|
||||
|
||||
+323
-9
@@ -25,7 +25,78 @@ behind such controllers can be manually added to GSmartControl using
|
||||
"Add Device..." functionality or --add-device command-line option.
|
||||
See https://www.smartmontools.org/wiki/Supported_RAID-Controllers .
|
||||
|
||||
https://gsmartcontrol.shaduri.dev
|
||||
https://gsmartcontrol.sourceforge.io/
|
||||
|
||||
|
||||
|
||||
Features
|
||||
|
||||
* automatically reports and highlights any anomalies;
|
||||
|
||||
* allows enabling/disabling SMART;
|
||||
|
||||
* allows enabling/disabling Automatic Offline Data Collection - a short
|
||||
self-check that the drive will perform automatically every four hours with no
|
||||
impact on performance;
|
||||
|
||||
* supports configuration of global and per-drive options for smartctl;
|
||||
|
||||
* performs SMART self-tests;
|
||||
|
||||
* displays drive identity information, capabilities, attributes,
|
||||
self-test/error logs, device statistics, etc...;
|
||||
|
||||
* can read in smartctl output from a saved file, interpreting it as a
|
||||
read-only virtual device;
|
||||
|
||||
* works on most smartctl-supported operating systems;
|
||||
|
||||
* has extensive help information.
|
||||
|
||||
|
||||
|
||||
What Is SMART?
|
||||
|
||||
Short answer: SMART is a technology which provides hard disk drives with
|
||||
methods to predict certain kinds of failures with certain chance of success.
|
||||
|
||||
Long answer: read below.
|
||||
|
||||
Self-Monitoring, Analysis, and Reporting Technology, or SMART, is a
|
||||
monitoring system for hard drives and SSDs to detect and report various
|
||||
indicators of reliability, in the hope of anticipating failures. SMART is
|
||||
implemented inside the drives, providing several ways of monitoring the drive
|
||||
health. It may present information about general health, various drive
|
||||
attributes (for example, number of unreadable sectors), error logs, and so on.
|
||||
It may also provide ways to instruct the drive to run various self-tests,
|
||||
which may report valuable information. It may even automatically scan the disk
|
||||
surface in when the drive is idle, repairing the defects while reallocating
|
||||
the data to more safe areas.
|
||||
|
||||
While having SMART sounds really good, there are some nuances to consider. One
|
||||
of the common pitfalls is that it may create a false sense of security. That
|
||||
is, a perfectly good SMART data is NOT an indication that the drive won't fail
|
||||
the next minute. The reverse is also true - some drives may function perfectly
|
||||
even with not-so-good-looking SMART data. However, as studies indicate, given
|
||||
a large population of drives, some SMART attributes may reliably predict
|
||||
drive failures within up to two months.
|
||||
|
||||
Another common mistake is to assume that the attribute values are the real
|
||||
physical values, as experienced by the drive. As manufacturers do not
|
||||
necessarily agree on precise attribute definitions and measurement units, the
|
||||
exact meaning of the attributes may vary greatly across different drive
|
||||
models.
|
||||
|
||||
At present SMART is implemented individually by manufacturers. While some
|
||||
aspects are standardized for compatibility, others are not. In fact, most
|
||||
manufacturers refer the users to their own health monitoring utilities and
|
||||
advice against taking SMART data seriously. Nevertheless, SMART may prove an
|
||||
effective measure against data loss.
|
||||
|
||||
Yet another issue is that quite often the drives have bugs which prevent
|
||||
correct SMART usage. This is usually due to buggy firmware, or the
|
||||
manufacturer ignoring the standards. Luckily, smartmontools usually detects
|
||||
these bugs and works around them.
|
||||
|
||||
|
||||
|
||||
@@ -33,31 +104,99 @@ Software Requirements
|
||||
|
||||
Note: If using the official Windows package, no additional software is required.
|
||||
|
||||
Build requirements:
|
||||
* pcre 1 - http://www.pcre.org .
|
||||
You need to have the following software installed:
|
||||
|
||||
* pcre - http://www.pcre.org .
|
||||
|
||||
* smartmontools - see https://www.smartmontools.org/ .
|
||||
|
||||
* GTK+, version 3.4 or higher - see http://www.gtk.org .
|
||||
|
||||
* Gtkmm, version 3.4 or higher - see http://www.gtkmm.org .
|
||||
|
||||
Runtime requirements:
|
||||
* smartmontools - see https://www.smartmontools.org/ .
|
||||
* xterm
|
||||
Most of these packages are probably already provided by your distribution.
|
||||
Here are the packages you need to have to build GSmartControl on some Linux
|
||||
distributions:
|
||||
|
||||
openSUSE, SLES, SLED:
|
||||
gcc-c++, pcre-devel, gtkmm3-devel.
|
||||
|
||||
Fedora, CentOS, RHEL:
|
||||
gcc-c++, pcre-devel, gtkmm30-devel.
|
||||
|
||||
Ubuntu, Debian GNU/Linux:
|
||||
g++, libpcre3-dev, libgtkmm-3.0-dev.
|
||||
|
||||
Note that usually you need to specify only these packages - the rest is
|
||||
installed automatically by the package manager's dependency resolver. Keep in
|
||||
mind that you also need smartmontools to run the program.
|
||||
|
||||
|
||||
The following operating systems are supported:
|
||||
|
||||
* Linux - All the popular configurations should work.
|
||||
|
||||
* FreeBSD - Tested with DesktopBSD / x86.
|
||||
|
||||
* NetBSD - Tested with NetBSD / x86.
|
||||
|
||||
* OpenBSD - Tested with OpenBSD / x86-64.
|
||||
|
||||
* DragonFlyBSD - Code written but no testing has been performed yet. Expected
|
||||
to work without any issues.
|
||||
to work without any issues.
|
||||
|
||||
* Windows Vista SP2 (32-bit and 64-bit), Windows 7 SP1, Windows Server 2008,
|
||||
Windows 8.1, Windows 10. The Windows port uses pd0, pd1, etc...
|
||||
for physical drives 0, 1, etc... .
|
||||
Windows 8.1, Windows 10. The Windows port uses pd0, pd1, etc...
|
||||
for physical drives 0, 1, etc... .
|
||||
|
||||
* Mac OS X.
|
||||
|
||||
* Solaris.
|
||||
|
||||
* QNX - Code written but no testing has been performed yet.
|
||||
|
||||
|
||||
|
||||
Installation
|
||||
|
||||
Short answer: build and install via: ./configure; make; make install
|
||||
|
||||
Run gsmartcontrol-root to invoke gsmartcontrol with your desktop's su
|
||||
mechanism, or use the desktop menu entry.
|
||||
|
||||
|
||||
Long answer: read below.
|
||||
|
||||
First, check if you can find a pre-built package for your distribution or
|
||||
operating system - they usually provide the best integration and the easiest
|
||||
installation procedure. For Linux, one option is to try the openSUSE Build
|
||||
Service - it provides ready-to-install packages for various popular Linux
|
||||
distributions (openSUSE, Fedora, etc...). See
|
||||
http://download.opensuse.org/repositories/home:/alex_sh/ .
|
||||
|
||||
If you want to compile from source, check that you have all the required
|
||||
dependencies (see Software Requirements section). Then the usual
|
||||
|
||||
./configure; make; make install
|
||||
|
||||
will build and install it. Installation usually requires administrative
|
||||
privileges, but you don't need to install the program in order to run it
|
||||
directly from the build directory.
|
||||
|
||||
|
||||
|
||||
Smartctl Options
|
||||
|
||||
GSmartControl tries its best to guard the user from having to specify smartctl
|
||||
options. However, this is not always possible due to drive firmware bugs,
|
||||
unimplemented features, and so on. The smartctl manual page contains all the
|
||||
information you may need when dealing with smartctl.
|
||||
See https://www.smartmontools.org/browser/trunk/smartmontools/smartctl.8.in
|
||||
|
||||
Additional information is available at https://www.smartmontools.org/
|
||||
|
||||
|
||||
|
||||
Command Line Options
|
||||
|
||||
GSmartControl inherits options from GTK+ and other libraries, so be sure to
|
||||
@@ -96,6 +235,181 @@ Example: --add-device /dev/sda --add-device /dev/twa0::3ware,2 --add-device
|
||||
|
||||
|
||||
|
||||
Permission Problems
|
||||
|
||||
Short answer: you need to be root (that's Administrator in Windows).
|
||||
In X11, use kdesu, gnomesu, sux, xdg-su or similar.
|
||||
|
||||
Long answer: read below.
|
||||
|
||||
Most operating systems prohibit direct access to hardware to users with
|
||||
non-administrative privileges. Unfortunately, to access SMART data, smartctl
|
||||
needs to directly access the hard drive.
|
||||
|
||||
The provided X11 desktop and menu icons should show the "Please enter the root
|
||||
password" dialog boxes, and, after correct information is entered, should run
|
||||
this program with root privileges. The dialogs should be available in most
|
||||
commonly used X11 desktop environments.
|
||||
|
||||
Another way is to use the included gsmartcontrol-root script, which finds the
|
||||
available su program and runs gsmartcontrol with it.
|
||||
|
||||
Yet another way is to manually invoke the program with kdesu, gnomesu, sux or
|
||||
similar programs. For example,
|
||||
|
||||
kdesu -u root -c gsmartcontrol
|
||||
|
||||
will ask for root password and run gsmartcontrol with root privileges. Replace
|
||||
"kdesu" with "gnomesu" if using Gnome. The "sux" or "xdg-su" commands may also
|
||||
help, if neither KDE or GNOME are available.
|
||||
|
||||
Please don't set the "setuid" flag on smartctl binary. It is considered a
|
||||
security risk.
|
||||
|
||||
|
||||
|
||||
Enable SMART Permanently
|
||||
|
||||
Specifications say that once you set a SMART-related property, it will be
|
||||
preserved across reboots. So, when you, say, enable SMART and Automatic
|
||||
Offline Data Collection, both will stay enabled until you disable them.
|
||||
|
||||
However, BIOS, your operating system, your other operating systems (if
|
||||
present), and various startup programs may affect that. For example, BIOS may
|
||||
enable SMART each time you start your computer, so if you disabled SMART
|
||||
previously, it will be re-enabled on reboot.
|
||||
|
||||
The easiest way to work around this is to set the desired settings on system
|
||||
startup. You may use smartctl or smartd to do that. For example, to enable
|
||||
both SMART and Automatic Offline Data Collection on /dev/sda, one would write
|
||||
the following to the system startup script (e.g. boot.local, rc.local or
|
||||
similar on Linux):
|
||||
|
||||
smartctl -s on -o on /dev/sda
|
||||
|
||||
For more information, see smartctl and smartd documentation.
|
||||
|
||||
|
||||
|
||||
Known Issues
|
||||
|
||||
Only ATA drives (both PATA and SATA), various USB to ATA bridges and drives
|
||||
behind some RAID controllers are supported for now. The main reasons are:
|
||||
|
||||
* We can't support drives which don't work with smartmontools. This affects
|
||||
drives which don't support SMART or don't export SMART data correctly (e.g.
|
||||
some USB enclosures, RAIDs, etc...).
|
||||
|
||||
* Smartctl's output for SCSI drives is completely different compared to ATA.
|
||||
Also, SCSI drives are rarely found in desktop systems and the servers rarely
|
||||
have X11 / Gtkmm running, so this is a low priority task.
|
||||
|
||||
* I only have ATA drives, so testing anything else is very difficult.
|
||||
|
||||
Immediate Offline Tests are not supported. I haven't found a way to reliably
|
||||
monitor them yet. Besides, they run automatically anyway if Automatic Offline
|
||||
Data Collection is enabled.
|
||||
|
||||
Testing is only supported on drives which correctly report their progress
|
||||
information in capabilities.
|
||||
|
||||
Not all drives support disabling Automatic Offline Data Collection, even if
|
||||
they report otherwise. Unfortunately, there's no way to detect such drives.
|
||||
|
||||
The texts probably contain a lot of grammatical errors, English being my third
|
||||
language and all.
|
||||
|
||||
|
||||
|
||||
Reporting Bugs
|
||||
|
||||
If it is a SMART or drive-related problem, please try to test it with smartctl
|
||||
first. Chances are, the problem you're experiencing is not tied to
|
||||
GSmartControl, but is a drive firmware or smartctl problem. For example, to
|
||||
see a complete information about your /dev/sda drive, type the following in a
|
||||
terminal emulator (as root, using sudo or su):
|
||||
|
||||
smartctl -x /dev/sda
|
||||
|
||||
Note: If using Windows, the device name should be /dev/pd1 for the second
|
||||
physical drive, etc... . Run cmd as administrator first.
|
||||
|
||||
If you still think it's a GSmartControl issue, please collect the following
|
||||
information about your system. Without it, it may be very hard or impossible
|
||||
to fix the bug.
|
||||
|
||||
* Which operating system you use (for example, openSUSE Leap 42.3).
|
||||
|
||||
* Which version of GTK and Gtkmm you have installed. Finding this out is very
|
||||
distribution-specific. For example, on openSUSE it would be
|
||||
"rpm -q gtk3 gtkmm3". Some distributions have gtkmm30 instead. You may also
|
||||
search them in your distribution's graphical package manager, if there is one.
|
||||
|
||||
* Execution log from the program, if possible. To obtain it, run the program
|
||||
with -v option, e.g. (type the following in a terminal emulator or Run
|
||||
dialog):
|
||||
|
||||
gsmartcontrol-root -v
|
||||
|
||||
Note: On Windows, -v switch is on by default.
|
||||
|
||||
Perform the steps needed to reproduce the bug, then go to
|
||||
"Options -> View Execution Log", and click "Save All".
|
||||
|
||||
* Detailed description of steps you performed when the bug occurred.
|
||||
|
||||
Once you have this information, send an email to me, Alexander Shaduri
|
||||
<ashaduri 'at' gmail.com>. Note that I may refer you to smartmontools support
|
||||
if it's a bug in smartmontools and not GSmartControl. Normally, I won't
|
||||
redirect your support request to them myself, because they may ask questions
|
||||
which only you have the answers to.
|
||||
|
||||
Please read the "License and Copyright" and "Patch Licensing" sections before
|
||||
sending any patches.
|
||||
|
||||
|
||||
|
||||
License and Copyright
|
||||
|
||||
For license information, see LICENSE_gsmartcontrol.txt file.
|
||||
|
||||
You may notice that GSmartControl is not licensed under "GNU GPL version X or
|
||||
later", but under "GNU GPL version X and Y". I firmly believe that it's unwise
|
||||
to license a piece of code under non-existent licenses, whatever anyone else
|
||||
might say. The reason for this is that one simply CANNOT know that, say, in 20
|
||||
years FSF won't be bought by some corporation who will release GPL version Z
|
||||
which will completely reverse the reasons GPL was created for.
|
||||
|
||||
The removal of "or later" clause somewhat imposes responsibility on the
|
||||
copyright holders to review every future version of the license once it's
|
||||
released, and, if deemed acceptable, re-license the code under the new license
|
||||
(possibly retaining the old licenses). Unfortunately, this is a necessary
|
||||
inconvenience we will have to deal with.
|
||||
|
||||
|
||||
|
||||
Patch Licensing
|
||||
|
||||
Due to reasons described in "License and Copyright" section, to make it
|
||||
possible to re-license the code without tracking down all the people who ever
|
||||
wrote a patch, the copyrights of all minor patches must be assigned to the
|
||||
central copyright holder of the project. If the patch is major enough (that
|
||||
is, it forms a significant part of the program source code), the author may
|
||||
retain the copyright, if he or she chooses to do so. However, unless the
|
||||
author plans to maintain his part of the source code, he / she is humbly asked
|
||||
to consider assigning away his / her copyright. A simple "I disclaim all
|
||||
copyright to this patch" by the author is sufficient. All credits will be
|
||||
mentioned in product documentation, whatever the size of the patch is.
|
||||
|
||||
Please note that centralization of copyright is needed to maintain a
|
||||
reasonably healthy legal status of the project. Also note that this method is
|
||||
not unique - FSF and many other organizations require exactly the same thing.
|
||||
|
||||
Some contributors may have reasonable doubts about the future status of this
|
||||
project. Let me assure you that this project will never have more restrictive
|
||||
license than GPLv2. If, some time in the future, the GPL is somehow
|
||||
invalidated in court, the project will be re-licensed under similar (in
|
||||
spirit) license, if possible, or a license less restrictive than GPL (for
|
||||
example, the three-clause BSD license).
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ local scope destruction also works if using stack variables.
|
||||
|
||||
TODO:
|
||||
|
||||
-l defects support? (smartctl 6.6)
|
||||
Move README.txt contents to the site, make Help menu open it.
|
||||
|
||||
|
||||
Don't rely on smartctl return code (2), parse the output instead.
|
||||
@@ -36,7 +36,7 @@ Testing:
|
||||
If smartctl outputs gibberish while testing, the GUI hangs.
|
||||
|
||||
|
||||
Support RAID for these controllers (supported by smartctl 6.5):
|
||||
Support RAID for these controllers:
|
||||
https://www.smartmontools.org/wiki/Supported_RAID-Controllers
|
||||
|
||||
Adaptec (Windows, Linux using "-d aacraid")
|
||||
@@ -47,3 +47,7 @@ Support RAID for these controllers (supported by smartctl 6.5):
|
||||
HP CCISS (FreeBSD)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,982 +0,0 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the specified
|
||||
# version of the C++ standard. If necessary, add switches to CXX and
|
||||
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
|
||||
# or '14' (for the C++14 standard).
|
||||
#
|
||||
# The second argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
#
|
||||
# The third argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline support for the specified C++ standard is
|
||||
# required and that the macro should error out if no mode with that
|
||||
# support is found. If specified 'optional', then configuration proceeds
|
||||
# regardless, after defining HAVE_CXX${VERSION} if and only if a
|
||||
# supporting mode is found.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
# Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 7
|
||||
|
||||
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
|
||||
dnl (serial version number 13).
|
||||
|
||||
AX_REQUIRE_DEFINED([AC_MSG_WARN])
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
|
||||
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
|
||||
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
|
||||
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$2], [], [],
|
||||
[$2], [ext], [],
|
||||
[$2], [noext], [],
|
||||
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
|
||||
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
|
||||
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
|
||||
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
|
||||
ax_cv_cxx_compile_cxx$1,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[ax_cv_cxx_compile_cxx$1=yes],
|
||||
[ax_cv_cxx_compile_cxx$1=no])])
|
||||
if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
|
||||
ac_success=yes
|
||||
fi
|
||||
|
||||
m4_if([$2], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
switch="-std=gnu++${alternative}"
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
fi
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
|
||||
m4_if([$2], [ext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
dnl HP's aCC needs +std=c++11 according to:
|
||||
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
|
||||
dnl Cray's crayCC needs "-h std=c++11"
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
fi
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test x$ac_success = xyes; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
AC_LANG_POP([C++])
|
||||
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
|
||||
if test x$ac_success = xno; then
|
||||
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
|
||||
fi
|
||||
fi
|
||||
if test x$ac_success = xno; then
|
||||
HAVE_CXX$1=0
|
||||
AC_MSG_NOTICE([No compiler with C++$1 support was found])
|
||||
else
|
||||
HAVE_CXX$1=1
|
||||
AC_DEFINE(HAVE_CXX$1,1,
|
||||
[define if the compiler supports basic C++$1 syntax])
|
||||
fi
|
||||
AC_SUBST(HAVE_CXX$1)
|
||||
m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])])
|
||||
])
|
||||
|
||||
|
||||
dnl Test body for checking C++11 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
)
|
||||
|
||||
|
||||
dnl Test body for checking C++14 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
)
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
|
||||
)
|
||||
|
||||
dnl Tests for new features in C++11
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++11, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 201103L
|
||||
|
||||
#error "This is not a C++11 compiler"
|
||||
|
||||
#else
|
||||
|
||||
namespace cxx11
|
||||
{
|
||||
|
||||
namespace test_static_assert
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_final_override
|
||||
{
|
||||
|
||||
struct Base
|
||||
{
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
struct Derived : public Base
|
||||
{
|
||||
virtual void f() override {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_double_right_angle_brackets
|
||||
{
|
||||
|
||||
template < typename T >
|
||||
struct check {};
|
||||
|
||||
typedef check<void> single_type;
|
||||
typedef check<check<void>> double_type;
|
||||
typedef check<check<check<void>>> triple_type;
|
||||
typedef check<check<check<check<void>>>> quadruple_type;
|
||||
|
||||
}
|
||||
|
||||
namespace test_decltype
|
||||
{
|
||||
|
||||
int
|
||||
f()
|
||||
{
|
||||
int a = 1;
|
||||
decltype(a) b = 2;
|
||||
return a + b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_type_deduction
|
||||
{
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
struct is_same
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
auto
|
||||
add(T1 a1, T2 a2) -> decltype(a1 + a2)
|
||||
{
|
||||
return a1 + a2;
|
||||
}
|
||||
|
||||
int
|
||||
test(const int c, volatile int v)
|
||||
{
|
||||
static_assert(is_same<int, decltype(0)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(c)>::value == false, "");
|
||||
static_assert(is_same<int, decltype(v)>::value == false, "");
|
||||
auto ac = c;
|
||||
auto av = v;
|
||||
auto sumi = ac + av + 'x';
|
||||
auto sumf = ac + av + 1.0;
|
||||
static_assert(is_same<int, decltype(ac)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(av)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(sumi)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(sumf)>::value == false, "");
|
||||
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
|
||||
return (sumf > 0.0) ? sumi : add(c, v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_noexcept
|
||||
{
|
||||
|
||||
int f() { return 0; }
|
||||
int g() noexcept { return 0; }
|
||||
|
||||
static_assert(noexcept(f()) == false, "");
|
||||
static_assert(noexcept(g()) == true, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_constexpr
|
||||
{
|
||||
|
||||
template < typename CharT >
|
||||
unsigned long constexpr
|
||||
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
|
||||
{
|
||||
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
|
||||
}
|
||||
|
||||
template < typename CharT >
|
||||
unsigned long constexpr
|
||||
strlen_c(const CharT *const s) noexcept
|
||||
{
|
||||
return strlen_c_r(s, 0UL);
|
||||
}
|
||||
|
||||
static_assert(strlen_c("") == 0UL, "");
|
||||
static_assert(strlen_c("1") == 1UL, "");
|
||||
static_assert(strlen_c("example") == 7UL, "");
|
||||
static_assert(strlen_c("another\0example") == 7UL, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_rvalue_references
|
||||
{
|
||||
|
||||
template < int N >
|
||||
struct answer
|
||||
{
|
||||
static constexpr int value = N;
|
||||
};
|
||||
|
||||
answer<1> f(int&) { return answer<1>(); }
|
||||
answer<2> f(const int&) { return answer<2>(); }
|
||||
answer<3> f(int&&) { return answer<3>(); }
|
||||
|
||||
void
|
||||
test()
|
||||
{
|
||||
int i = 0;
|
||||
const int c = 0;
|
||||
static_assert(decltype(f(i))::value == 1, "");
|
||||
static_assert(decltype(f(c))::value == 2, "");
|
||||
static_assert(decltype(f(0))::value == 3, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_uniform_initialization
|
||||
{
|
||||
|
||||
struct test
|
||||
{
|
||||
static const int zero {};
|
||||
static const int one {1};
|
||||
};
|
||||
|
||||
static_assert(test::zero == 0, "");
|
||||
static_assert(test::one == 1, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambdas
|
||||
{
|
||||
|
||||
void
|
||||
test1()
|
||||
{
|
||||
auto lambda1 = [](){};
|
||||
auto lambda2 = lambda1;
|
||||
lambda1();
|
||||
lambda2();
|
||||
}
|
||||
|
||||
int
|
||||
test2()
|
||||
{
|
||||
auto a = [](int i, int j){ return i + j; }(1, 2);
|
||||
auto b = []() -> int { return '0'; }();
|
||||
auto c = [=](){ return a + b; }();
|
||||
auto d = [&](){ return c; }();
|
||||
auto e = [a, &b](int x) mutable {
|
||||
const auto identity = [](int y){ return y; };
|
||||
for (auto i = 0; i < a; ++i)
|
||||
a += b--;
|
||||
return x + identity(a + b);
|
||||
}(0);
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
|
||||
int
|
||||
test3()
|
||||
{
|
||||
const auto nullary = [](){ return 0; };
|
||||
const auto unary = [](int x){ return x; };
|
||||
using nullary_t = decltype(nullary);
|
||||
using unary_t = decltype(unary);
|
||||
const auto higher1st = [](nullary_t f){ return f(); };
|
||||
const auto higher2nd = [unary](nullary_t f1){
|
||||
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
|
||||
};
|
||||
return higher1st(nullary) + higher2nd(nullary)(unary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_variadic_templates
|
||||
{
|
||||
|
||||
template <int...>
|
||||
struct sum;
|
||||
|
||||
template <int N0, int... N1toN>
|
||||
struct sum<N0, N1toN...>
|
||||
{
|
||||
static constexpr auto value = N0 + sum<N1toN...>::value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct sum<>
|
||||
{
|
||||
static constexpr auto value = 0;
|
||||
};
|
||||
|
||||
static_assert(sum<>::value == 0, "");
|
||||
static_assert(sum<1>::value == 1, "");
|
||||
static_assert(sum<23>::value == 23, "");
|
||||
static_assert(sum<1, 2>::value == 3, "");
|
||||
static_assert(sum<5, 5, 11>::value == 21, "");
|
||||
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
|
||||
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
|
||||
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
|
||||
// because of this.
|
||||
namespace test_template_alias_sfinae
|
||||
{
|
||||
|
||||
struct foo {};
|
||||
|
||||
template<typename T>
|
||||
using member = typename T::member_type;
|
||||
|
||||
template<typename T>
|
||||
void func(...) {}
|
||||
|
||||
template<typename T>
|
||||
void func(member<T>*) {}
|
||||
|
||||
void test();
|
||||
|
||||
void test() { func<foo>(0); }
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx11
|
||||
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++14
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++14, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 201402L
|
||||
|
||||
#error "This is not a C++14 compiler"
|
||||
|
||||
#else
|
||||
|
||||
namespace cxx14
|
||||
{
|
||||
|
||||
namespace test_polymorphic_lambdas
|
||||
{
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
const auto lambda = [](auto&&... args){
|
||||
const auto istiny = [](auto x){
|
||||
return (sizeof(x) == 1UL) ? 1 : 0;
|
||||
};
|
||||
const int aretiny[] = { istiny(args)... };
|
||||
return aretiny[0];
|
||||
};
|
||||
return lambda(1, 1L, 1.0f, '1');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_binary_literals
|
||||
{
|
||||
|
||||
constexpr auto ivii = 0b0000000000101010;
|
||||
static_assert(ivii == 42, "wrong value");
|
||||
|
||||
}
|
||||
|
||||
namespace test_generalized_constexpr
|
||||
{
|
||||
|
||||
template < typename CharT >
|
||||
constexpr unsigned long
|
||||
strlen_c(const CharT *const s) noexcept
|
||||
{
|
||||
auto length = 0UL;
|
||||
for (auto p = s; *p; ++p)
|
||||
++length;
|
||||
return length;
|
||||
}
|
||||
|
||||
static_assert(strlen_c("") == 0UL, "");
|
||||
static_assert(strlen_c("x") == 1UL, "");
|
||||
static_assert(strlen_c("test") == 4UL, "");
|
||||
static_assert(strlen_c("another\0test") == 7UL, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambda_init_capture
|
||||
{
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
auto x = 0;
|
||||
const auto lambda1 = [a = x](int b){ return a + b; };
|
||||
const auto lambda2 = [a = lambda1(x)](){ return a; };
|
||||
return lambda2();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_digit_separators
|
||||
{
|
||||
|
||||
constexpr auto ten_million = 100'000'000;
|
||||
static_assert(ten_million == 100000000, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_return_type_deduction
|
||||
{
|
||||
|
||||
auto f(int& x) { return x; }
|
||||
decltype(auto) g(int& x) { return x; }
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
struct is_same
|
||||
{
|
||||
static constexpr auto value = false;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static constexpr auto value = true;
|
||||
};
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
auto x = 0;
|
||||
static_assert(is_same<int, decltype(f(x))>::value, "");
|
||||
static_assert(is_same<int&, decltype(g(x))>::value, "");
|
||||
return x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx14
|
||||
|
||||
#endif // __cplusplus >= 201402L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++17
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++17, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus <= 201402L
|
||||
|
||||
#error "This is not a C++17 compiler"
|
||||
|
||||
#else
|
||||
|
||||
#if defined(__clang__)
|
||||
#define REALLY_CLANG
|
||||
#else
|
||||
#if defined(__GNUC__)
|
||||
#define REALLY_GCC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace cxx17
|
||||
{
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_constexpr_lambdas
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
constexpr int foo = [](){return 42;}();
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test::nested_namespace::definitions
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
namespace test_fold_expression
|
||||
{
|
||||
|
||||
template<typename... Args>
|
||||
int multiply(Args... args)
|
||||
{
|
||||
return (args * ... * 1);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
bool all(Args... args)
|
||||
{
|
||||
return (args && ...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_static_assert
|
||||
{
|
||||
|
||||
static_assert (true);
|
||||
|
||||
}
|
||||
|
||||
namespace test_auto_brace_init_list
|
||||
{
|
||||
|
||||
auto foo = {5};
|
||||
auto bar {5};
|
||||
|
||||
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
|
||||
static_assert(std::is_same<int, decltype(bar)>::value);
|
||||
}
|
||||
|
||||
namespace test_typename_in_template_template_parameter
|
||||
{
|
||||
|
||||
template<template<typename> typename X> struct D;
|
||||
|
||||
}
|
||||
|
||||
namespace test_fallthrough_nodiscard_maybe_unused_attributes
|
||||
{
|
||||
|
||||
int f1()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
[[nodiscard]] int f2()
|
||||
{
|
||||
[[maybe_unused]] auto unused = f1();
|
||||
|
||||
switch (f1())
|
||||
{
|
||||
case 17:
|
||||
f1();
|
||||
[[fallthrough]];
|
||||
case 42:
|
||||
f1();
|
||||
}
|
||||
return f1();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_aggregate_initialization
|
||||
{
|
||||
|
||||
struct base1
|
||||
{
|
||||
int b1, b2 = 42;
|
||||
};
|
||||
|
||||
struct base2
|
||||
{
|
||||
base2() {
|
||||
b3 = 42;
|
||||
}
|
||||
int b3;
|
||||
};
|
||||
|
||||
struct derived : base1, base2
|
||||
{
|
||||
int d;
|
||||
};
|
||||
|
||||
derived d1 {{1, 2}, {}, 4}; // full initialization
|
||||
derived d2 {{}, {}, 4}; // value-initialized bases
|
||||
|
||||
}
|
||||
|
||||
namespace test_general_range_based_for_loop
|
||||
{
|
||||
|
||||
struct iter
|
||||
{
|
||||
int i;
|
||||
|
||||
int& operator* ()
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
const int& operator* () const
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
iter& operator++()
|
||||
{
|
||||
++i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct sentinel
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
bool operator== (const iter& i, const sentinel& s)
|
||||
{
|
||||
return i.i == s.i;
|
||||
}
|
||||
|
||||
bool operator!= (const iter& i, const sentinel& s)
|
||||
{
|
||||
return !(i == s);
|
||||
}
|
||||
|
||||
struct range
|
||||
{
|
||||
iter begin() const
|
||||
{
|
||||
return {0};
|
||||
}
|
||||
|
||||
sentinel end() const
|
||||
{
|
||||
return {5};
|
||||
}
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
range r {};
|
||||
|
||||
for (auto i : r)
|
||||
{
|
||||
[[maybe_unused]] auto v = i;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambda_capture_asterisk_this_by_value
|
||||
{
|
||||
|
||||
struct t
|
||||
{
|
||||
int i;
|
||||
int foo()
|
||||
{
|
||||
return [*this]()
|
||||
{
|
||||
return i;
|
||||
}();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_enum_class_construction
|
||||
{
|
||||
|
||||
enum class byte : unsigned char
|
||||
{};
|
||||
|
||||
byte foo {42};
|
||||
|
||||
}
|
||||
|
||||
namespace test_constexpr_if
|
||||
{
|
||||
|
||||
template <bool cond>
|
||||
int f ()
|
||||
{
|
||||
if constexpr(cond)
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_selection_statement_with_initializer
|
||||
{
|
||||
|
||||
int f()
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
|
||||
int f2()
|
||||
{
|
||||
if (auto i = f(); i > 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
switch (auto i = f(); i + 4)
|
||||
{
|
||||
case 17:
|
||||
return 2;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_template_argument_deduction_for_class_templates
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
pair (T1 p1, T2 p2)
|
||||
: m1 {p1},
|
||||
m2 {p2}
|
||||
{}
|
||||
|
||||
T1 m1;
|
||||
T2 m2;
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
[[maybe_unused]] auto p = pair{13, 42u};
|
||||
}
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test_non_type_auto_template_parameters
|
||||
{
|
||||
|
||||
template <auto n>
|
||||
struct B
|
||||
{};
|
||||
|
||||
B<5> b1;
|
||||
B<'a'> b2;
|
||||
|
||||
}
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_structured_bindings
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
int arr[2] = { 1, 2 };
|
||||
std::pair<int, int> pr = { 1, 2 };
|
||||
|
||||
auto f1() -> int(&)[2]
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
auto f2() -> std::pair<int, int>&
|
||||
{
|
||||
return pr;
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int x1 : 2;
|
||||
volatile double y1;
|
||||
};
|
||||
|
||||
S f3()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto [ x1, y1 ] = f1();
|
||||
auto& [ xr1, yr1 ] = f1();
|
||||
auto [ x2, y2 ] = f2();
|
||||
auto& [ xr2, yr2 ] = f2();
|
||||
const auto [ x3, y3 ] = f3();
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_exception_spec_type_system
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
struct Good {};
|
||||
struct Bad {};
|
||||
|
||||
void g1() noexcept;
|
||||
void g2();
|
||||
|
||||
template<typename T>
|
||||
Bad
|
||||
f(T*, T*);
|
||||
|
||||
template<typename T1, typename T2>
|
||||
Good
|
||||
f(T1*, T2*);
|
||||
|
||||
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test_inline_variables
|
||||
{
|
||||
|
||||
template<class T> void f(T)
|
||||
{}
|
||||
|
||||
template<class T> inline T g(T)
|
||||
{
|
||||
return T{};
|
||||
}
|
||||
|
||||
template<> inline void f<>(int)
|
||||
{}
|
||||
|
||||
template<> int g<>(int)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx17
|
||||
|
||||
#endif // __cplusplus <= 201402L
|
||||
|
||||
]])
|
||||
@@ -48,7 +48,6 @@ case $type in
|
||||
--enable-optimize-options --enable-tests --host=i686-w64-mingw32" ;;
|
||||
win32-cross-debug)
|
||||
flags="PATH=\"/usr/i686-w64-mingw32/bin:/usr/i686-w64-mingw32/sys-root/mingw/bin:$PATH\" \
|
||||
--with-windows-sysroot=/usr/i686-w64-mingw32/sys-root/mingw \
|
||||
--enable-debug-options --enable-tests --host=i686-w64-mingw32" ;;
|
||||
win64-cross)
|
||||
flags="PATH=\"/usr/x86_64-w64-mingw32/bin:/usr/x86_64-w64-mingw32/sys-root/mingw/bin:$PATH\" \
|
||||
@@ -56,7 +55,6 @@ case $type in
|
||||
--enable-optimize-options --enable-tests --host=x86_64-w64-mingw32" ;;
|
||||
win64-cross-debug)
|
||||
flags="PATH=\"/usr/x86_64-w64-mingw32/bin:/usr/x86_64-w64-mingw32/sys-root/mingw/bin:$PATH\" \
|
||||
--with-windows-sysroot=/usr/x86_64-w64-mingw32/sys-root/mingw \
|
||||
--enable-debug-options --enable-tests --host=x86_64-w64-mingw32" ;;
|
||||
|
||||
win32-msys)
|
||||
@@ -65,7 +63,6 @@ case $type in
|
||||
--enable-optimize-options --enable-tests --host=i686-w64-mingw32" ;;
|
||||
win32-msys-debug)
|
||||
flags="PATH=\"/mingw32/i686-w64-mingw32:/mingw32/bin:$PATH\" \
|
||||
--with-windows-sysroot=/mingw32 \
|
||||
--enable-debug-options --enable-tests --host=i686-w64-mingw32" ;;
|
||||
win64-msys)
|
||||
flags="PATH=\"/mingw64/x86_64-w64-mingw32:/mingw64/bin:$PATH\" \
|
||||
@@ -73,7 +70,6 @@ case $type in
|
||||
--enable-optimize-options --enable-tests --host=x86_64-w64-mingw32" ;;
|
||||
win64-msys-debug)
|
||||
flags="PATH=\"/mingw64/x86_64-w64-mingw32:/mingw64/bin:$PATH\" \
|
||||
--with-windows-sysroot=/mingw64 \
|
||||
--enable-debug-options --enable-tests --host=x86_64-w64-mingw32" ;;
|
||||
esac
|
||||
|
||||
|
||||
+14
-11
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_INIT([GSmartControl],[1.1.4],[],[gsmartcontrol])
|
||||
AC_INIT([GSmartControl],[1.1.0],[],[gsmartcontrol])
|
||||
|
||||
AC_CONFIG_SRCDIR([configure.ac])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -64,10 +64,6 @@ APP_DETECT_OS_KERNEL([build], [CONFIG_HOST_KERNEL_])
|
||||
# which is important for some compatibility flags (e.g. __func__ visibility, etc...).
|
||||
APP_COMPILER_OPTIONS([])
|
||||
|
||||
# Enable C++11 support. This is implied by gtkmm3, but CentOS7 fails to add it
|
||||
# to gtkmm flags, so we have to enable it manually. Make it optional for Debian 7 (gcc 4.7).
|
||||
AX_CXX_COMPILE_STDCXX([11], [], [optional])
|
||||
|
||||
# Thread support for known configurations.
|
||||
# Sun compiler (at least on linux) has some runtime issues with stringstream
|
||||
# unless we use the thread flags. Also, Linux-based gdb fails to debug
|
||||
@@ -313,11 +309,12 @@ AC_SUBST(WINDOWS_ARCH)
|
||||
RES_FILES="src/res/gsc_about_dialog.ui \
|
||||
src/res/gsc_add_device_window.ui \
|
||||
src/res/gsc_executor_log_window.ui \
|
||||
src/res/gsc_help_window.ui \
|
||||
src/res/gsc_info_window.ui \
|
||||
src/res/gsc_main_window.ui \
|
||||
src/res/gsc_preferences_window.ui \
|
||||
src/res/gsc_text_window.ui \
|
||||
AUTHORS.txt LICENSE_gsmartcontrol.txt"
|
||||
AUTHORS.txt LICENSE_gsmartcontrol.txt README.txt"
|
||||
|
||||
# Unfortunately, _SOURCES can't contain substitutions, so we use LIBADD.
|
||||
RES_LIBADD="" # .o file to put into .a, libres_a_LIBADD, libres_a_DEPENDENCIES.
|
||||
@@ -340,7 +337,7 @@ do # on separate line for portability
|
||||
fi
|
||||
|
||||
if test "$RES_BASE_EXT" = "ui"; then
|
||||
RES_LIBADD="$RES_LIBADD $RES_BASE_NOEXT.ui.$ac_objext" # file.ui.o
|
||||
RES_LIBADD="$RES_LIBADD $RES_BASE_NOEXT.ui.$ac_objext" # file.ui.o or file.glade.o
|
||||
RES_TARGETS="$RES_TARGETS
|
||||
$RES_BASE_NOEXT.ui.cpp: $RES_FILE_CANON
|
||||
\"\$(top_srcdir)/file2csource.sh\" \"$RES_FILE_CANON\" \"$RES_BASE_NOEXT.ui.cpp\" \"$RES_BASE_NOEXT\"_ui
|
||||
@@ -453,8 +450,6 @@ AC_SUBST(LDFLAGS)
|
||||
# print them out for debug purposes
|
||||
|
||||
AC_MSG_NOTICE([
|
||||
CXX:
|
||||
$CXX
|
||||
CXXFLAGS:
|
||||
$CXXFLAGS
|
||||
LDFLAGS:
|
||||
@@ -474,7 +469,11 @@ AC_SUBST(AUTODIRS)
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
AC_CONFIG_FILES([data/gsmartcontrol.desktop data/gsmartcontrol.appdata.xml data/nsis/distribution.txt data/nsis/gsmartcontrol.nsi debian.dist/changelog src/gsc_winres.rc src/gsmartcontrol.exe.manifest gsmartcontrol.spec version.txt compilation_flags])
|
||||
AC_CONFIG_FILES([ data/gsmartcontrol.desktop data/gsmartcontrol.appdata.xml \
|
||||
data/nsis/distribution.txt data/nsis/gsmartcontrol.nsi \
|
||||
debian.dist/changelog \
|
||||
src/gsc_winres.rc src/gsmartcontrol.exe.manifest \
|
||||
gsmartcontrol.spec version compilation_flags ])
|
||||
|
||||
|
||||
AC_CONFIG_FILES([data/gsmartcontrol-root], [chmod +x data/gsmartcontrol-root])
|
||||
@@ -482,7 +481,11 @@ AC_CONFIG_FILES([data/gsmartcontrol-root], [chmod +x data/gsmartcontrol-root])
|
||||
|
||||
# these are all the makefiles to generate
|
||||
|
||||
AC_CONFIG_FILES([Makefile src/Makefile src/applib/Makefile src/res/Makefile src/hz/Makefile src/libdebug/Makefile src/rconfig/Makefile src/rmn/Makefile data/Makefile data/16/Makefile data/22/Makefile data/24/Makefile data/32/Makefile data/48/Makefile data/64/Makefile data/128/Makefile data/256/Makefile data/nsis/Makefile debian.dist/Makefile])
|
||||
AC_CONFIG_FILES([Makefile src/Makefile src/applib/Makefile src/res/Makefile src/hz/Makefile \
|
||||
src/libdebug/Makefile src/rconfig/Makefile src/rmn/Makefile \
|
||||
data/Makefile data/16/Makefile data/22/Makefile data/24/Makefile data/32/Makefile \
|
||||
data/48/Makefile data/64/Makefile data/128/Makefile data/256/Makefile data/nsis/Makefile \
|
||||
debian.dist/Makefile])
|
||||
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -71,7 +71,7 @@ fi
|
||||
|
||||
|
||||
# They're basically the same, only the order is different.
|
||||
# pkexec is for PolKit.
|
||||
# pkexec is for PolKit
|
||||
# sux requires xterm to ask for the password.
|
||||
# xdg-su is basically like this script, except worse :)
|
||||
# su-to-root is a debian/ubuntu official method (although gksu is available).
|
||||
@@ -102,7 +102,7 @@ if [ "$GSMARTCONTROL_SU" = "" ]; then
|
||||
|
||||
if [ "$found_su" = "" ]; then
|
||||
xmessage "Error launching ${prog_name}: No suitable su mechanism found.
|
||||
Try installing PolKit, kdesu, gnomesu, gksu, beesu or sux first.";
|
||||
Try installing kdesu, gnomesu, gksu, beesu or sux first.";
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
@@ -138,12 +138,6 @@ if [ "$GSMARTCONTROL_SU" != "" ]; then
|
||||
full_cmd="$GSMARTCONTROL_SU '$EXEC_BIN $final_args_quoted'";
|
||||
|
||||
elif [ "$found_su" = "pkexec" ]; then
|
||||
if [ "$GDK_SCALE" != "" ]; then
|
||||
final_args_quoted="$final_args_quoted --gdk-scale='$GDK_SCALE'"
|
||||
fi
|
||||
if [ "$GDK_DPI_SCALE" != "" ]; then
|
||||
final_args_quoted="$final_args_quoted --gdk-dpi-scale='$GDK_DPI_SCALE'"
|
||||
fi
|
||||
full_cmd="pkexec --disable-internal-agent $EXEC_BIN $final_args_quoted";
|
||||
|
||||
elif [ "$found_su" = "sux" ]; then
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright 2017 - 2022 GSmartControl developers -->
|
||||
<!-- Copyright 2017 GSmartControl developers -->
|
||||
<component type="desktop">
|
||||
<id>gsmartcontrol</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
@@ -16,7 +16,7 @@
|
||||
</p>
|
||||
</description>
|
||||
<launchable type="desktop-id">gsmartcontrol.desktop</launchable>
|
||||
<url type="homepage">https://gsmartcontrol.shaduri.dev</url>
|
||||
<url type="homepage">https://gsmartcontrol.sourceforge.io</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Main window</caption>
|
||||
|
||||
@@ -9,11 +9,8 @@ Categories=System;Monitor;
|
||||
Name=GSmartControl
|
||||
# short description, usually shown in parentheses after Name
|
||||
GenericName=Hard Disk and SSD Health Inspection
|
||||
GenericName[fr]=Inspecteur de santé de disque dur et de SSD
|
||||
|
||||
# tooltip
|
||||
Comment=Monitor and control SMART data on hard disk and solid-state drives
|
||||
Comment[fr]=Surveille et contrôle les données SMART des disques durs et des SSD
|
||||
|
||||
# If it's a name only, it looks for "name.[png|xpm]" file in
|
||||
# $XDG_DATA_DIRS/icons and /usr/share/pixmaps.
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.8 KiB |
@@ -4,7 +4,7 @@ Version @VERSION@
|
||||
|
||||
The latest version of this distribution, as well as the source code of
|
||||
GSmartControl, can be found at
|
||||
https://gsmartcontrol.shaduri.dev
|
||||
https://gsmartcontrol.sourceforge.io
|
||||
and
|
||||
https://sourceforge.net/projects/gsmartcontrol/files/
|
||||
|
||||
@@ -15,7 +15,7 @@ This distribution includes:
|
||||
The binary was compiled against Gtkmm (http://www.gtkmm.org/), GTK+
|
||||
(http://gtk.org/) and related libraries, and PCRE (http://www.pcre.org/).
|
||||
|
||||
* Smartctl binaries (from smartmontools 6.6, http://smartmontools.sf.net/)
|
||||
* Smartctl binaries (from smartmontools 6.5, http://smartmontools.sf.net/)
|
||||
- smartctl-nc.exe (compiled without console output), smartctl.exe (compiled
|
||||
with console output), update-smart-drivedb.exe (drive database updater).
|
||||
|
||||
|
||||
@@ -4,13 +4,11 @@
|
||||
; Compatible with NSIS Unicode 2.45.
|
||||
; Public Domain
|
||||
|
||||
Unicode True
|
||||
|
||||
!define PRODUCT_VERSION "@VERSION@"
|
||||
!define PRODUCT_NAME "GSmartControl"
|
||||
!define PRODUCT_NAME_SMALL "gsmartcontrol"
|
||||
!define PRODUCT_PUBLISHER "Alexander Shaduri"
|
||||
!define PRODUCT_WEB_SITE "https://gsmartcontrol.shaduri.dev"
|
||||
!define PRODUCT_WEB_SITE "https://gsmartcontrol.sourceforge.io"
|
||||
|
||||
;!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\AppMainExe.exe"
|
||||
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
@@ -136,6 +134,7 @@ SectionIn 1 RO
|
||||
SetOverwrite On
|
||||
File *.exe
|
||||
File *.dll
|
||||
File gsmartcontrol.exe.manifest
|
||||
File gsmartcontrol.ico
|
||||
File icon_*.png
|
||||
File drivedb.h
|
||||
@@ -146,7 +145,6 @@ SectionIn 1 RO
|
||||
; GTK and stuff
|
||||
File /r etc
|
||||
File /r share
|
||||
File /r lib
|
||||
|
||||
; Add Shortcuts (this inherits the exe's run permissions)
|
||||
CreateShortCut "$SMPROGRAMS\GSmartControl.lnk" "$INSTDIR\gsmartcontrol.exe" "" \
|
||||
@@ -228,6 +226,7 @@ Section Uninstall
|
||||
|
||||
Delete "$INSTDIR\*.exe"
|
||||
Delete "$INSTDIR\*.dll"
|
||||
Delete "$INSTDIR\gsmartcontrol.exe.manifest"
|
||||
Delete "$INSTDIR\gsmartcontrol.ico"
|
||||
Delete "$INSTDIR\icon_*.png"
|
||||
|
||||
@@ -240,7 +239,6 @@ Section Uninstall
|
||||
; GTK and stuff
|
||||
RMDir /r "$INSTDIR\etc"
|
||||
RMDir /r "$INSTDIR\share"
|
||||
RMDir /r "$INSTDIR\lib"
|
||||
|
||||
; clean up generated stuff
|
||||
Delete "$INSTDIR\*stdout.txt"
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
9
|
||||
5
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
Source: gsmartcontrol
|
||||
Section: utils
|
||||
Priority: extra
|
||||
Homepage: https://gsmartcontrol.shaduri.dev
|
||||
Homepage: https://gsmartcontrol.sourceforge.io/
|
||||
Maintainer: Alexander Shaduri <ashaduriREMOVETHIS@gmail.com>
|
||||
Build-Depends: debhelper (>= 5), autotools-dev,
|
||||
libpcre3-dev, libgtkmm-3.0-dev (>= 3.4.0)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
This package was debianized by Alexander Shaduri <ashaduri 'at' gmail.com> on
|
||||
Sat, 15 Nov 2008 00:12:04 +0400.
|
||||
|
||||
It was downloaded from <https://gsmartcontrol.shaduri.dev>
|
||||
It was downloaded from <https://gsmartcontrol.sourceforge.io/>
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 2008 - 2022 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
Copyright (C) 2008 - 2017 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
|
||||
License:
|
||||
|
||||
@@ -27,6 +27,6 @@ On Debian systems, the complete text of the GNU General
|
||||
Public Licenses can be found in `/usr/share/common-licenses/GPL-2' and
|
||||
`/usr/share/common-licenses/GPL-3'.
|
||||
|
||||
The Debian packaging is (C) 2008 - 2022 Alexander Shaduri <ashaduri 'at' gmail.com> and
|
||||
The Debian packaging is (C) 2008 - 2017 Alexander Shaduri <ashaduri 'at' gmail.com> and
|
||||
is licensed under the GPLv2 and GPLv3, see above.
|
||||
|
||||
|
||||
+1
-6
@@ -24,12 +24,7 @@ fi
|
||||
in_file="$1";
|
||||
out_file="$2";
|
||||
sym_name="$3";
|
||||
size="";
|
||||
if [[ $OSTYPE == 'darwin'* ]]; then
|
||||
size=`stat "-f%z" "$in_file"`
|
||||
else
|
||||
size=`stat -c "%s" "$in_file"`
|
||||
fi
|
||||
size=`stat -c "%s" "$in_file"`
|
||||
|
||||
|
||||
# header. extern means "global" in this context (needed because const
|
||||
|
||||
@@ -6,7 +6,7 @@ Name: gsmartcontrol
|
||||
Version: @VERSION@
|
||||
Release: 0
|
||||
License: GPL-2.0 AND GPL-3.0
|
||||
Url: https://gsmartcontrol.shaduri.dev
|
||||
Url: https://gsmartcontrol.sourceforge.io/
|
||||
Vendor: Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
# Packager: Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
Source: http://sourceforge.net/projects/gsmartcontrol/files/%{version}/%{name}-%{version}.tar.bz2
|
||||
|
||||
+2
-2
@@ -31,9 +31,9 @@ gsmartcontrol_LDADD = $(top_builddir)/src/applib/libapplib.a \
|
||||
$(top_builddir)/src/res/libres.a $(WINRES_OBJ)
|
||||
|
||||
noinst_HEADERS = global_macros.h gsc_about_dialog.h gsc_add_device_window.h gsc_executor_error_dialog.h \
|
||||
gsc_executor_log_window.h gsc_info_window.h gsc_init.h gsc_main_window.h \
|
||||
gsc_executor_log_window.h gsc_help_window.h gsc_info_window.h gsc_init.h gsc_main_window.h \
|
||||
gsc_main_window_iconview.h gsc_preferences_window.h gsc_settings.h gsc_text_window.h
|
||||
gsmartcontrol_SOURCES = $(WIN_MAIN_SRC) gsc_about_dialog.cpp gsc_add_device_window.cpp \
|
||||
gsc_executor_error_dialog.cpp gsc_executor_log_window.cpp gsc_info_window.cpp \
|
||||
gsc_executor_error_dialog.cpp gsc_executor_log_window.cpp gsc_help_window.cpp gsc_info_window.cpp \
|
||||
gsc_init.cpp gsc_main.cpp gsc_main_window.cpp gsc_preferences_window.cpp
|
||||
|
||||
|
||||
@@ -63,6 +63,24 @@ void app_gtkmm_set_widget_tooltip(Gtk::Widget& widget,
|
||||
|
||||
|
||||
|
||||
bool app_gtkmm_icon_theme_has_icon(Glib::RefPtr<Gtk::IconTheme> theme,
|
||||
const Glib::ustring& icon_name, int size)
|
||||
{
|
||||
if (!theme || !theme->has_icon(icon_name)) // check if it exists first, or exception may be thrown.
|
||||
return false;
|
||||
|
||||
std::vector<int> sizes = theme->get_icon_sizes(icon_name);
|
||||
|
||||
for (std::vector<int>::const_iterator iter = sizes.begin(); iter != sizes.end(); ++iter) {
|
||||
if (*iter == size || *iter == -1) // -1 means scalable
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
/// This has been copied from _g_utf8_make_valid() (glib-2.20.4).
|
||||
|
||||
@@ -68,6 +68,11 @@ int app_gtkmm_create_tree_view_column(Gtk::TreeModelColumn<T>& mcol, Gtk::TreeVi
|
||||
|
||||
|
||||
|
||||
/// Check whether the icon theme has the specified icon of size \c size.
|
||||
bool app_gtkmm_icon_theme_has_icon(Glib::RefPtr<Gtk::IconTheme> theme,
|
||||
const Glib::ustring& icon_name, int size);
|
||||
|
||||
|
||||
/// Get Glib::ustring from gchar*, freeing gchar*.
|
||||
Glib::ustring app_ustring_from_gchar(gchar* str);
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
/// \def APP_UI_RES_DATA_INIT(res_name)
|
||||
/// Use these in window class definitions to declare ui resources.
|
||||
/// E.g. APP_UI_RES_DATA_INIT(main_window) will search for
|
||||
/// main_window.ui in data file search paths.
|
||||
/// main_window.glade or main_window.ui (depending on whether
|
||||
/// you're using libglade or gtkbuilder) in data file search paths.
|
||||
/// Or, if you're using compiled-in buffers, it will make them available.
|
||||
#define APP_UI_RES_DATA_INIT(res_name) \
|
||||
HZ_RES_DATA_INIT_NAMED(res_name##_ui, #res_name ".ui", UIResDataBase); \
|
||||
@@ -90,10 +91,10 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref,
|
||||
|
||||
|
||||
|
||||
// These allow easy attaching of gtkbuilder widget signals to member functions
|
||||
// These allow easy attaching of glade widget signals to member functions
|
||||
|
||||
/// Connect member function (callback) to signal \c signal_name on widget
|
||||
/// \c ui_element, where \c ui_element is the widget's gtkbuilder name.
|
||||
/// \c ui_element, where \c ui_element is the widget's glade/gtkbuilder name.
|
||||
#define APP_UI_RES_CONNECT(ui_element, signal_name, callback) \
|
||||
if (true) { \
|
||||
if (!ui_element) \
|
||||
@@ -106,7 +107,7 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref,
|
||||
|
||||
/// Connect member function (callback) with a name of \c on_<widget_name>_<signal_name>
|
||||
/// to signal \c signal_name on widget \c ui_element, where \c ui_element is the
|
||||
/// widget's gtkbuilder name.
|
||||
/// widget's glade/gtkbuilder name.
|
||||
#define APP_UI_RES_AUTO_CONNECT(ui_element, signal_name) \
|
||||
APP_UI_RES_CONNECT(ui_element, signal_name, on_ ## ui_element ## _ ## signal_name)
|
||||
|
||||
@@ -114,7 +115,7 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref,
|
||||
|
||||
|
||||
|
||||
/// Inherit this when using GtkBuilder-enabled windows (or any other GtkBuilder-enabled objects).
|
||||
/// Inherit this when using Glade-enabled windows (or any other glade-enabled objects).
|
||||
/// \c Child is the child class that inherits all the functionality of having instance lifetime
|
||||
/// management and other benefits.
|
||||
/// If \c MultiInstance is false, create() will return the same instance each time.
|
||||
@@ -136,7 +137,7 @@ class AppUIResWidget : public WidgetType, public hz::InstanceManager<Child, Mult
|
||||
|
||||
std::string error;
|
||||
app_ui_res_ref_t ui = Gtk::Builder::create();
|
||||
const typename Child::UIResData data; // this holds the GtkBuilder data
|
||||
const typename Child::UIResData data; // this holds the glade data
|
||||
|
||||
// this does the actual object construction
|
||||
bool success = app_ui_res_create_from(ui, data.buf, data.size, error);
|
||||
@@ -225,13 +226,13 @@ class AppUIResWidget : public WidgetType, public hz::InstanceManager<Child, Mult
|
||||
|
||||
protected:
|
||||
|
||||
typedef Child self_type; ///< This is needed by APP_UI_ macros
|
||||
typedef WidgetType widget_type; ///< This is needed by APP_UI_ macros
|
||||
typedef Child self_type; ///< This is needed by APP_GLADE_ macros
|
||||
typedef WidgetType widget_type; ///< This is needed by APP_GLADE_ macros
|
||||
|
||||
|
||||
// protected constructor / destructor, use create() / destroy() instead of new / delete.
|
||||
|
||||
/// GtkBuilder needs this constructor in a child.
|
||||
/// Glade needs this constructor in a child.
|
||||
/// BaseObjectType is a C type, defined in specific Gtk:: widget class.
|
||||
AppUIResWidget(typename WidgetType::BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui)
|
||||
: WidgetType(gtkcobj), ref_ui_(ref_ui)
|
||||
@@ -239,7 +240,7 @@ class AppUIResWidget : public WidgetType, public hz::InstanceManager<Child, Mult
|
||||
// manually connecting signals:
|
||||
// this->signal_delete_event().connect(sigc::mem_fun(*this, &MainWindow::on_main_window_delete));
|
||||
|
||||
// signals of GtkBuilder-created objects:
|
||||
// signals of glade-created objects:
|
||||
// Gtk::ToolButton* rescan_devices_toolbutton = 0;
|
||||
// APP_UI_RES_AUTO_CONNECT(rescan_devices_toolbutton, clicked);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class AppUiResTestWindow : public AppUIResWidget<AppUiResTestWindow, false>
|
||||
{
|
||||
public:
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(app_ui_res_test_window);
|
||||
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ bool Cmdex::execute()
|
||||
#endif
|
||||
|
||||
hz::ScopedEnv lang_env("LANG", "C", change_lang);
|
||||
hz::ScopedEnv lc_numeric_env("LC_NUMERIC", "C", change_lang);
|
||||
|
||||
|
||||
debug_out_info("app", DBG_FUNC_MSG << "Executing \"" << cmd << "\".\n");
|
||||
/*
|
||||
@@ -253,13 +253,8 @@ bool Cmdex::execute()
|
||||
bool Cmdex::try_stop(hz::signal_t sig)
|
||||
{
|
||||
DBG_FUNCTION_ENTER_MSG;
|
||||
#ifdef _WIN32
|
||||
if (!this->running_ || this->pid_ == 0)
|
||||
return false;
|
||||
#else
|
||||
if (!this->running_ || this->pid_ <= 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// other variants: SIGHUP(1) (terminal closed), SIGINT(2) (Ctrl-C),
|
||||
// SIGKILL(9) (kill).
|
||||
|
||||
@@ -29,7 +29,7 @@ bool CmdexSyncGui::execute()
|
||||
|
||||
|
||||
#define CMDEX_DIALOG_MESSAGE_TYPE Gtk::MESSAGE_OTHER
|
||||
#define CMDEX_DIALOG_HINT_TYPE Gdk::WINDOW_TYPE_HINT_DIALOG
|
||||
#define CMDEX_DIALOG_HINT_TYPE Gdk::WINDOW_TYPE_HINT_NOTIFICATION
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -345,7 +345,6 @@ std::string SmartctlParser::parse_byte_size(const std::string& str, uint64_t& by
|
||||
to_replace.push_back(",");
|
||||
to_replace.push_back(".");
|
||||
to_replace.push_back(std::string(1, 0xa0));
|
||||
to_replace.push_back(std::string(1, 0xc2));
|
||||
|
||||
#ifdef _WIN32
|
||||
// if current locale is C, then probably we didn't change it at application
|
||||
@@ -853,20 +852,16 @@ bool SmartctlParser::parse_section_data(const std::string& body)
|
||||
// "SCT Commands not supported"
|
||||
// "SCT Commands not supported if ATA Security is LOCKED"
|
||||
// "Error unknown SCT Temperature History Format Version (3), should be 2."
|
||||
// "Another SCT command is executing, abort Read Data Table"
|
||||
|| app_pcre_match("/^SCT Commands not supported/mi", sub)
|
||||
|| app_pcre_match("/^SCT Data Table command not supported/mi", sub)
|
||||
|| app_pcre_match("/^Error unknown SCT Temperature History Format Version/mi", sub)
|
||||
|| app_pcre_match("/^Another SCT command is executing, abort Read Data Table/mi", sub)
|
||||
|| app_pcre_match("/^Warning: device does not support SCT Commands/mi", sub) ) { // old smartctl
|
||||
status = parse_section_data_subsection_scttemp_log(sub) || status;
|
||||
|
||||
} else if (app_pcre_match("/^SCT Error Recovery Control/mi", sub)
|
||||
// Can be the same "SCT Commands not supported" as scttemp.
|
||||
// "Another SCT command is executing, abort Error Recovery Control"
|
||||
|| app_pcre_match("/^SCT Error Recovery Control command not supported/mi", sub)
|
||||
|| app_pcre_match("/^SCT \\(Get\\) Error Recovery Control command failed/mi", sub)
|
||||
|| app_pcre_match("/^Another SCT command is executing, abort Error Recovery Control/mi", sub)
|
||||
|| app_pcre_match("/^Warning: device does not support SCT \\(Get\\) Error Recovery Control/mi", sub) ) { // old smartctl
|
||||
status = parse_section_data_subsection_scterc_log(sub) || status;
|
||||
|
||||
|
||||
@@ -88,20 +88,13 @@ The drives may be duplicated as pdX (with X and N being unrelated).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct DriveLetterInfo {
|
||||
std::set<int> physical_drives; ///< N in pdN
|
||||
std::string volume_name; ///< Volume name
|
||||
};
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
/// Check which physical drives each drive letter (C, D, ...) spans across.
|
||||
std::map<char, DriveLetterInfo> win32_get_drive_letter_map()
|
||||
std::map<char, std::set<int> > win32_get_drive_letter_map()
|
||||
{
|
||||
std::map<char, DriveLetterInfo> drive_letter_map;
|
||||
std::map<char, std::set<int> > drive_letter_map;
|
||||
|
||||
std::bitset<32> drives(GetLogicalDrives());
|
||||
|
||||
@@ -110,7 +103,7 @@ std::map<char, DriveLetterInfo> win32_get_drive_letter_map()
|
||||
for (char c = 'A'; c <= 'Z'; ++c) {
|
||||
if (drives[c - 'A']) { // drive is present
|
||||
debug_out_dump("app", "Windows drive found: " << c << ".\n");
|
||||
if (GetDriveType((c + std::string(":\\")).c_str()) == DRIVE_FIXED) {
|
||||
if (GetDriveType((c + string(":\\")).c_str()) == DRIVE_FIXED) {
|
||||
debug_out_dump("app", "Windows drive " << c << " is fixed.\n");
|
||||
good_drives.push_back(c);
|
||||
}
|
||||
@@ -120,7 +113,7 @@ std::map<char, DriveLetterInfo> win32_get_drive_letter_map()
|
||||
// Try to open each drive, check its disk extents
|
||||
for (std::size_t i = 0; i < good_drives.size(); ++i) {
|
||||
char drive = good_drives[i];
|
||||
std::string drive_str = std::string("\\\\.\\") + drive + ":";
|
||||
string drive_str = string("\\\\.\\") + drive + ":";
|
||||
HANDLE h = CreateFileA(
|
||||
drive_str.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS, NULL);
|
||||
@@ -137,27 +130,12 @@ std::map<char, DriveLetterInfo> win32_get_drive_letter_map()
|
||||
continue;
|
||||
}
|
||||
|
||||
std::set<int> physical_drives;
|
||||
std::set<int> drive_numbers;
|
||||
for (int i = 0; i < vde.NumberOfDiskExtents; ++i) {
|
||||
physical_drives.insert(vde.Extents[i].DiskNumber);
|
||||
drive_numbers.insert(vde.Extents[i].DiskNumber);
|
||||
debug_out_dump("app", "Windows drive " << drive << " corresponds to physical drive " << vde.Extents[i].DiskNumber << ".\n");
|
||||
}
|
||||
|
||||
std::string volume_name;
|
||||
wchar_t volume_name_w[MAX_PATH+1] = {0};
|
||||
DWORD dummy = 0;
|
||||
hz::scoped_array<wchar_t> drive_name(hz::win32_utf8_to_utf16((drive + std::string(":\\")).c_str()));
|
||||
if (drive_name && GetVolumeInformationW(drive_name.get(),
|
||||
volume_name_w, MAX_PATH+1,
|
||||
NULL, &dummy, &dummy, NULL, 0)) {
|
||||
volume_name = hz::win32_utf16_to_utf8_string(volume_name_w);
|
||||
}
|
||||
|
||||
DriveLetterInfo dli;
|
||||
dli.physical_drives = physical_drives;
|
||||
dli.volume_name = volume_name;
|
||||
|
||||
drive_letter_map[drive] = dli;
|
||||
drive_letter_map[drive] = drive_numbers;
|
||||
}
|
||||
|
||||
return drive_letter_map;
|
||||
@@ -170,7 +148,7 @@ std::map<char, DriveLetterInfo> win32_get_drive_letter_map()
|
||||
/// conflict with pd* devices, and we like pd* better than sd*.
|
||||
std::string get_scan_open_multiport_devices(std::vector<StorageDeviceRefPtr>& drives,
|
||||
ExecutorFactoryRefPtr ex_factory,
|
||||
const std::map<char, DriveLetterInfo>& drive_letter_map,
|
||||
const std::map<char, std::set<int> >& drive_letter_map,
|
||||
std::set<int>& equivalent_pds)
|
||||
{
|
||||
debug_out_info("app", "Getting multi-port devices through smartctl --scan-open...\n");
|
||||
@@ -237,13 +215,13 @@ std::string get_scan_open_multiport_devices(std::vector<StorageDeviceRefPtr>& dr
|
||||
std::string full_dev = dev + "," + port_str;
|
||||
StorageDeviceRefPtr drive(new StorageDevice(full_dev, type));
|
||||
|
||||
std::map<char, std::string> letters_volnames;
|
||||
for (std::map<char, DriveLetterInfo>::const_iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.physical_drives.count(drive_num) > 0) {
|
||||
letters_volnames[iter->first] = iter->second.volume_name;
|
||||
std::vector<char> drive_letters;
|
||||
for (std::map<char, std::set<int> >::const_iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.count(drive_num) > 0) {
|
||||
drive_letters.push_back(iter->first);
|
||||
}
|
||||
}
|
||||
drive->set_drive_letters(letters_volnames);
|
||||
drive->set_drive_letters(drive_letters);
|
||||
|
||||
drives.push_back(drive);
|
||||
}
|
||||
@@ -654,7 +632,7 @@ std::string detect_drives_win32(std::vector<StorageDeviceRefPtr>& drives, Execut
|
||||
|
||||
// Construct drive letter map
|
||||
debug_out_info("app", "Checking which drive corresponds to which \\\\.\\PhysicalDriveN device...\n");
|
||||
std::map<char, DriveLetterInfo> drive_letter_map = win32_get_drive_letter_map();
|
||||
std::map<char, std::set<int> > drive_letter_map = win32_get_drive_letter_map();
|
||||
|
||||
|
||||
hz::intrusive_ptr<CmdexSync> smartctl_ex = ex_factory->create_executor(ExecutorFactory::ExecutorSmartctl);
|
||||
@@ -733,14 +711,14 @@ std::string detect_drives_win32(std::vector<StorageDeviceRefPtr>& drives, Execut
|
||||
|
||||
StorageDeviceRefPtr drive(new StorageDevice(hz::string_sprintf("pd%d", drive_num)));
|
||||
|
||||
std::map<char, std::string> letters_volnames;
|
||||
for (std::map<char, DriveLetterInfo>::const_iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.physical_drives.count(drive_num) > 0) {
|
||||
letters_volnames[iter->first] = iter->second.volume_name;
|
||||
std::vector<char> letters;
|
||||
for (std::map<char, std::set<int> >::iterator iter = drive_letter_map.begin(); iter != drive_letter_map.end(); ++iter) {
|
||||
if (iter->second.count(drive_num) > 0) {
|
||||
letters.push_back(iter->first);
|
||||
}
|
||||
}
|
||||
drive->set_drive_letters(letters_volnames);
|
||||
debug_out_dump("app", "Drive letters for: " << drive->get_device() << ": " << drive->format_drive_letters(true) << ".\n");
|
||||
drive->set_drive_letters(letters);
|
||||
debug_out_dump("app", "Drive letters for: " << drive->get_device() << ": " << drive->format_drive_letters() << ".\n");
|
||||
|
||||
// Sometimes, a single physical drive may be accessible from both "/.//PhysicalDriveN"
|
||||
// and "/.//Scsi2" (e.g. pd0 and csmi2,1). Prefer the port-having ones (which is from --scan-open),
|
||||
|
||||
@@ -651,28 +651,25 @@ std::string StorageDevice::get_extra_arguments() const
|
||||
|
||||
|
||||
|
||||
void StorageDevice::set_drive_letters(const std::map<char, std::string>& letters)
|
||||
void StorageDevice::set_drive_letters(const std::vector< char >& letters)
|
||||
{
|
||||
drive_letters_ = letters;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::map<char, std::string>& StorageDevice::get_drive_letters() const
|
||||
const std::vector< char >& StorageDevice::get_drive_letters() const
|
||||
{
|
||||
return drive_letters_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string StorageDevice::format_drive_letters(bool with_volnames) const
|
||||
std::string StorageDevice::format_drive_letters() const
|
||||
{
|
||||
std::vector<std::string> drive_letters_decorated;
|
||||
for (std::map<char, std::string>::const_iterator iter = drive_letters_.begin(); iter != drive_letters_.end(); ++iter) {
|
||||
drive_letters_decorated.push_back(std::string() + (char)std::toupper(iter->first) + ":");
|
||||
if (with_volnames && !iter->second.empty()) {
|
||||
drive_letters_decorated.back() += std::string(" (") + iter->second + ")";
|
||||
}
|
||||
for (std::size_t i = 0; i < drive_letters_.size(); ++i) {
|
||||
drive_letters_decorated.push_back(std::string() + (char)std::toupper(drive_letters_[i]) + ":");
|
||||
}
|
||||
return hz::string_join(drive_letters_decorated, ", ");
|
||||
}
|
||||
@@ -815,7 +812,7 @@ std::string StorageDevice::get_save_filename() const
|
||||
{
|
||||
std::string model = this->get_model_name(); // may be empty
|
||||
std::string serial = this->get_serial_number();
|
||||
std::string date = hz::format_date("%Y-%m-%d_%H%M", true);
|
||||
std::string date = hz::format_date("%Y-%m-%d", false);
|
||||
|
||||
std::string filename_format;
|
||||
rconfig::get_data("gui/smartctl_output_filename_format", filename_format);
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#define STORAGE_DEVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <sigc++/sigc++.h>
|
||||
|
||||
#include "hz/optional_value.h"
|
||||
@@ -167,13 +166,13 @@ class StorageDevice : public hz::intrusive_ptr_referenced {
|
||||
|
||||
|
||||
/// Set windows drive letters for this drive
|
||||
void set_drive_letters(const std::map<char, std::string>& letters_volnames);
|
||||
void set_drive_letters(const std::vector<char>& letters);
|
||||
|
||||
/// Get windows drive letters for this drive
|
||||
const std::map<char, std::string>& get_drive_letters() const;
|
||||
const std::vector<char>& get_drive_letters() const;
|
||||
|
||||
/// Get comma-separated win32 drive letters (if present)
|
||||
std::string format_drive_letters(bool with_volnames) const;
|
||||
std::string format_drive_letters() const;
|
||||
|
||||
|
||||
/// Get "virtual" status
|
||||
@@ -276,7 +275,7 @@ class StorageDevice : public hz::intrusive_ptr_referenced {
|
||||
std::string type_arg_; ///< Device type (for -d smartctl parameter), as specified when adding the device.
|
||||
std::string extra_args_; ///< Extra parameters for smartctl, as specified when adding the device.
|
||||
|
||||
std::map<char, std::string> drive_letters_; ///< Windows drive letters (if detected), with volume names
|
||||
std::vector<char> drive_letters_; ///< Windows drive letters (if detected)
|
||||
|
||||
bool is_virtual_; ///< If true, then this is not a real device - merely a loaded description of it.
|
||||
std::string virtual_file_; ///< A file (smartctl data) the virtual device was loaded from
|
||||
|
||||
@@ -43,12 +43,7 @@ std::string StorageAttribute::format_raw_value() const
|
||||
// If it's fully a number, format it with commas
|
||||
if (hz::number_to_string(raw_value_int) == raw_value) {
|
||||
std::stringstream ss;
|
||||
try {
|
||||
ss.imbue(std::locale(""));
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
// something is wrong with system locale, can't do anything here.
|
||||
}
|
||||
ss.imbue(std::locale(""));
|
||||
ss << std::fixed << raw_value_int;
|
||||
return ss.str();
|
||||
}
|
||||
@@ -71,25 +66,6 @@ std::ostream& operator<< (std::ostream& os, const StorageAttribute& p)
|
||||
|
||||
|
||||
|
||||
std::string StorageStatistic::format_value() const
|
||||
{
|
||||
// If it's fully a number, format it with commas
|
||||
if (hz::number_to_string(value_int) == value) {
|
||||
std::stringstream ss;
|
||||
try {
|
||||
ss.imbue(std::locale(""));
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
// something is wrong with system locale, can't do anything here.
|
||||
}
|
||||
ss << std::fixed << value_int;
|
||||
return ss.str();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const StorageStatistic& p)
|
||||
{
|
||||
os << p.value;
|
||||
@@ -163,12 +139,7 @@ int StorageErrorBlock::get_warning_level_for_error_type(std::string& type)
|
||||
std::string StorageErrorBlock::format_lifetime_hours() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
try {
|
||||
ss.imbue(std::locale(""));
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
// something is wrong with system locale, can't do anything here.
|
||||
}
|
||||
ss.imbue(std::locale(""));
|
||||
ss << std::fixed << lifetime_hours;
|
||||
return ss.str();
|
||||
}
|
||||
@@ -188,12 +159,7 @@ std::ostream& operator<< (std::ostream& os, const StorageErrorBlock& b)
|
||||
std::string StorageSelftestEntry::format_lifetime_hours() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
try {
|
||||
ss.imbue(std::locale(""));
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
// something is wrong with system locale, can't do anything here.
|
||||
}
|
||||
ss.imbue(std::locale(""));
|
||||
ss << std::fixed << lifetime_hours;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -162,9 +162,6 @@ class StorageStatistic {
|
||||
return flags.find('N') != flags.npos;
|
||||
}
|
||||
|
||||
/// Format value with commas (if it's a number)
|
||||
std::string format_value() const;
|
||||
|
||||
bool is_header; ///< If the line is a header
|
||||
std::string flags; ///< Flags in "NDC" / "---" format
|
||||
std::string value; ///< Value as a string, as presented by smartctl (formatted).
|
||||
|
||||
@@ -1677,7 +1677,7 @@ StorageProperty::warning_t storage_property_autoset_warning(StorageProperty& p)
|
||||
|
||||
} else if (name_match(p, "smart_enabled") && !p.value_bool) {
|
||||
w = StorageProperty::warning_notice;
|
||||
reason = "SMART is disabled. You should enable it to read any SMART information from this drive. "
|
||||
reason = "SMART is disabled. You shoud enable it to read any SMART information from this drive. "
|
||||
"Additionally, some drives do not log useful data with SMART disabled, so it's advisable to keep it always enabled.";
|
||||
|
||||
} else if (name_match(p, "info_warning")) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
|
||||
|
||||
// GtkBuilder needs this constructor
|
||||
// glade/gtkbuilder needs this constructor
|
||||
GscAboutDialog::GscAboutDialog(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui)
|
||||
: AppUIResWidget<GscAboutDialog, false, Gtk::AboutDialog>(gtkcobj, ref_ui)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ GscAboutDialog::GscAboutDialog(BaseObjectType* gtkcobj, const app_ui_res_ref_t&
|
||||
set_version(VERSION);
|
||||
|
||||
// set these properties here (after setting hooks) to make the links work.
|
||||
set_website("https://gsmartcontrol.shaduri.dev");
|
||||
set_website("https://gsmartcontrol.sourceforge.io/");
|
||||
|
||||
set_license(LicenseTextResData().get_string());
|
||||
|
||||
@@ -50,7 +50,7 @@ GscAboutDialog::GscAboutDialog(BaseObjectType* gtkcobj, const app_ui_res_ref_t&
|
||||
// #endif
|
||||
|
||||
// spammers go away
|
||||
set_copyright("Copyright (C) 2008 - 2022 Alexander Shaduri " "<ashaduri" "" "@" "" "" "gmail.com>");
|
||||
set_copyright("Copyright (C) 2008 - 2017 Alexander Shaduri " "<ashaduri" "" "@" "" "" "gmail.com>");
|
||||
|
||||
|
||||
std::string authors_str = AuthorsTextResData().get_string();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
class GscAboutDialog : public AppUIResWidget<GscAboutDialog, false, Gtk::AboutDialog> {
|
||||
public:
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_about_dialog);
|
||||
|
||||
// we need the license file to show it.
|
||||
@@ -35,7 +35,7 @@ class GscAboutDialog : public AppUIResWidget<GscAboutDialog, false, Gtk::AboutDi
|
||||
HZ_RES_DATA_INIT_NAMED(AUTHORS_txt, "AUTHORS.txt", AuthorsTextResData);
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscAboutDialog(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui);
|
||||
|
||||
/// Virtual destructor
|
||||
|
||||
@@ -26,11 +26,11 @@ class GscMainWindow;
|
||||
class GscAddDeviceWindow : public AppUIResWidget<GscAddDeviceWindow, true> {
|
||||
public:
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_add_device_window);
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscAddDeviceWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui);
|
||||
|
||||
/// Virtual destructor
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
class GscExecutorLogWindow : public AppUIResWidget<GscExecutorLogWindow, false> {
|
||||
public:
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_executor_log_window);
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscExecutorLogWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui);
|
||||
|
||||
/// Virtual destructor
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
/// \file
|
||||
/// \author Alexander Shaduri
|
||||
/// \ingroup gsc
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
#include <vector>
|
||||
#include <gtkmm.h>
|
||||
#include <gdk/gdk.h> // GDK_KEY_Escape
|
||||
#include "applib/app_gtkmm_features.h"
|
||||
|
||||
#include "hz/string_algo.h"
|
||||
#include "applib/app_gtkmm_utils.h" // app_gtkmm_create_tree_view_column
|
||||
#include "applib/app_pcrecpp.h"
|
||||
|
||||
#include "gsc_help_window.h"
|
||||
|
||||
|
||||
|
||||
HZ_RES_DATA_INIT_NAMED(README_txt, "README.txt", ReadmeTextResData);
|
||||
|
||||
|
||||
|
||||
GscHelpWindow::GscHelpWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui)
|
||||
: AppUIResWidget<GscHelpWindow, false>(gtkcobj, ref_ui), selection_callback_enabled(true)
|
||||
{
|
||||
// Connect callbacks
|
||||
|
||||
APP_GTKMM_CONNECT_VIRTUAL(delete_event); // make sure the event handler is called
|
||||
|
||||
Gtk::Button* window_close_button = 0;
|
||||
APP_UI_RES_AUTO_CONNECT(window_close_button, clicked);
|
||||
|
||||
|
||||
// Accelerators
|
||||
|
||||
Glib::RefPtr<Gtk::AccelGroup> accel_group = this->get_accel_group();
|
||||
if (window_close_button) {
|
||||
window_close_button->add_accelerator("clicked", accel_group, GDK_KEY_Escape,
|
||||
Gdk::ModifierType(0), Gtk::AccelFlags(0));
|
||||
}
|
||||
|
||||
|
||||
// --------------- Make a treeview
|
||||
|
||||
Gtk::TreeView* treeview = this->lookup_widget<Gtk::TreeView*>("topics_treeview");
|
||||
if (treeview) {
|
||||
Gtk::TreeModelColumnRecord model_columns;
|
||||
// Topic
|
||||
model_columns.add(col_topic);
|
||||
app_gtkmm_create_tree_view_column(col_topic, *treeview, "Topic", "Topic");
|
||||
|
||||
// create a TreeModel (ListStore)
|
||||
list_store = Gtk::ListStore::create(model_columns);
|
||||
treeview->set_model(list_store);
|
||||
|
||||
selection = treeview->get_selection();
|
||||
selection->signal_changed().connect(sigc::mem_fun(*this,
|
||||
&self_type::on_tree_selection_changed) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------------- Parse help text
|
||||
|
||||
/*
|
||||
README.txt File Format
|
||||
|
||||
The whole text is converted to unix newline format before parsing.
|
||||
Sections are separated by 3 newlines (two empty lines).
|
||||
The first line of the section is its header.
|
||||
When splitting the file to sections and headers, any leading or trailing
|
||||
whitespace is removed.
|
||||
If there is a single newline inside a section, it is converted to
|
||||
space to enable correct wrapping.
|
||||
If there are two consequent newlines, they are left as they are,
|
||||
essentially making a paragraph break.
|
||||
*/
|
||||
|
||||
std::string readme = hz::string_any_to_unix_copy(ReadmeTextResData().get_string());
|
||||
|
||||
|
||||
// Paragraphs are delimited by 3 empty lines
|
||||
std::vector<std::string> topics;
|
||||
hz::string_split(readme, "\n\n\n\n", topics, true); // skip empty
|
||||
|
||||
|
||||
// Add to treeview and textview
|
||||
|
||||
Gtk::TextView* content = this->lookup_widget<Gtk::TextView*>("content_textview");
|
||||
|
||||
if (treeview && content) {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = content->get_buffer();
|
||||
|
||||
buffer->create_mark("Begin", buffer->begin(), true);
|
||||
|
||||
for (unsigned int i = 0; i < topics.size(); ++i) {
|
||||
std::string topic = hz::string_trim_copy(topics[i]);
|
||||
|
||||
// The first line of topic is its title
|
||||
std::vector<std::string> topic_split;
|
||||
hz::string_split(topic, "\n\n", topic_split, true, 2); // skip empty, get 2 elements only
|
||||
|
||||
if (topic_split.size() < 2) {
|
||||
debug_out_warn("app", DBG_FUNC_MSG << "Cannot extract topic title in topic " << i << "\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string topic_title = hz::string_trim_copy(topic_split[0]);
|
||||
std::string topic_body = hz::string_trim_copy(topic_split[1]);
|
||||
|
||||
buffer->create_mark(topic_title, buffer->end(), true); // set topic mark to the end of what's there
|
||||
|
||||
// add the title and make it bold
|
||||
buffer->insert(buffer->end(), "\n" + topic_title);
|
||||
|
||||
Gtk::TextIter first = buffer->end(), last = first;
|
||||
first.backward_lines(1);
|
||||
|
||||
Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
|
||||
tag->property_weight() = Pango::WEIGHT_BOLD;
|
||||
tag->property_size_points() = 14;
|
||||
|
||||
buffer->apply_tag(tag, first, last);
|
||||
|
||||
// add the rest
|
||||
|
||||
// single newlines to spaces, to allow proper wrapping.
|
||||
app_pcre_replace("/([^\\n])\\n([^\\n])/", "\\1 \\2", topic_body);
|
||||
buffer->insert(buffer->end(), "\n\n" + topic_body + "\n\n");
|
||||
|
||||
|
||||
// Add to treeview
|
||||
|
||||
Gtk::TreeRow row = *(list_store->append());
|
||||
row[col_topic] = topic_title;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ---------------
|
||||
|
||||
|
||||
// show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GscHelpWindow::set_topic(const Glib::ustring& topic)
|
||||
{
|
||||
this->selection_callback_enabled = false; // temporarily disable it
|
||||
|
||||
// scroll to it
|
||||
|
||||
Gtk::TextView* content = this->lookup_widget<Gtk::TextView*>("content_textview");
|
||||
if (content) {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = content->get_buffer();
|
||||
|
||||
Glib::RefPtr<Gtk::TextMark> mark = buffer->get_mark(topic);
|
||||
if (mark)
|
||||
content->scroll_to(mark, 0., 0., 0.);
|
||||
}
|
||||
|
||||
// select it in tree view
|
||||
Gtk::TreeView* treeview = this->lookup_widget<Gtk::TreeView*>("topics_treeview");
|
||||
|
||||
if (treeview && !list_store->children().empty()) {
|
||||
for (Gtk::TreeIter iter = list_store->children().begin(); iter != list_store->children().end(); ++iter) {
|
||||
if (iter->get_value(col_topic) == topic) {
|
||||
selection->select(*iter);
|
||||
// about 30% from top
|
||||
treeview->scroll_to_cell(list_store->get_path(iter), *(treeview->get_column(0)), 0.3f, 0.f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->selection_callback_enabled = true; // enable it back
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GscHelpWindow::on_delete_event_before(GdkEventAny* e)
|
||||
{
|
||||
destroy(this);
|
||||
return true; // event handled, don't call default virtual handler
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GscHelpWindow::on_window_close_button_clicked()
|
||||
{
|
||||
destroy(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GscHelpWindow::on_tree_selection_changed()
|
||||
{
|
||||
if (!this->selection_callback_enabled)
|
||||
return;
|
||||
|
||||
if (selection->count_selected_rows()) {
|
||||
Gtk::TreeIter iter = selection->get_selected();
|
||||
Gtk::TreeRow row = *iter;
|
||||
|
||||
set_topic(row[col_topic]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// @}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**************************************************************************
|
||||
Copyright:
|
||||
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
|
||||
License: See LICENSE_gsmartcontrol.txt
|
||||
***************************************************************************/
|
||||
/// \file
|
||||
/// \author Alexander Shaduri
|
||||
/// \ingroup gsc
|
||||
/// \weakgroup gsc
|
||||
/// @{
|
||||
|
||||
#ifndef GSC_HELP_WINDOW_H
|
||||
#define GSC_HELP_WINDOW_H
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include "applib/app_ui_res_utils.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/// The Help window.
|
||||
/// Use create() / destroy() with this class instead of new / delete!
|
||||
class GscHelpWindow : public AppUIResWidget<GscHelpWindow, false> {
|
||||
public:
|
||||
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_help_window);
|
||||
|
||||
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscHelpWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui);
|
||||
|
||||
/// Virtual destructor
|
||||
virtual ~GscHelpWindow()
|
||||
{ }
|
||||
|
||||
|
||||
/// Set the current help topic
|
||||
void set_topic(const Glib::ustring& topic);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// ---------- overriden virtual methods
|
||||
|
||||
/// Destroy this object on delete event (by default it calls hide()).
|
||||
/// Reimplemented from Gtk::Window.
|
||||
bool on_delete_event_before(GdkEventAny* e);
|
||||
|
||||
|
||||
// ---------- other callbacks
|
||||
|
||||
/// Button click callback
|
||||
void on_window_close_button_clicked();
|
||||
|
||||
/// Callback
|
||||
void on_tree_selection_changed();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Glib::RefPtr<Gtk::ListStore> list_store; ///< List store
|
||||
Glib::RefPtr<Gtk::TreeSelection> selection; ///< Tree selection
|
||||
|
||||
Gtk::TreeModelColumn<Glib::ustring> col_topic; /// Tree column
|
||||
|
||||
bool selection_callback_enabled; ///< Helper for set_topic(), temporarily disables the tree selection changed callback
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
+7
-38
@@ -127,12 +127,10 @@ namespace {
|
||||
crt->property_cell_background().reset_value();
|
||||
crt->property_foreground().reset_value();
|
||||
}
|
||||
if (p->value_type == StorageProperty::value_type_statistic) {
|
||||
if (p->value_statistic.is_header) {
|
||||
crt->property_weight() = Pango::WEIGHT_BOLD;
|
||||
} else {
|
||||
crt->property_weight().reset_value();
|
||||
}
|
||||
if (p->value_statistic.is_header) {
|
||||
crt->property_weight() = Pango::WEIGHT_BOLD;
|
||||
} else {
|
||||
crt->property_weight().reset_value();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -466,7 +464,7 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
{
|
||||
std::string device = Glib::Markup::escape_text(drive->get_device_with_type());
|
||||
std::string model = Glib::Markup::escape_text(drive->get_model_name().empty() ? "Unknown model" : drive->get_model_name());
|
||||
std::string drive_letters = Glib::Markup::escape_text(drive->format_drive_letters(false));
|
||||
std::string drive_letters = Glib::Markup::escape_text(drive->format_drive_letters());
|
||||
|
||||
this->set_title("Device Information - " + device + ": " + model + " - GSmartControl");
|
||||
|
||||
@@ -818,7 +816,7 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
Gtk::TreeRow row = *(list_store->append());
|
||||
|
||||
row[col_description] = (iter->value_statistic.is_header ? iter->readable_name : (" " + iter->readable_name));
|
||||
row[col_value] = iter->value_statistic.format_value();
|
||||
row[col_value] = iter->value_statistic.value;
|
||||
row[col_flags] = iter->value_statistic.flags; // it's a string, not int.
|
||||
row[col_page_offset] = (iter->value_statistic.is_header ? std::string()
|
||||
: hz::string_sprintf("0x%02x, 0x%03x", int(iter->value_statistic.page), int(iter->value_statistic.offset)));
|
||||
@@ -1130,12 +1128,8 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
if (buffer) {
|
||||
buffer->set_text("\nComplete error log:\n\n" + iter->value_string);
|
||||
|
||||
// Make the text monospace (the 3.16+ glade property does not work anymore for some reason).
|
||||
Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
|
||||
tag->property_family() = "Monospace";
|
||||
buffer->apply_tag(tag, buffer->begin(), buffer->end());
|
||||
// set marks so we can scroll to them
|
||||
|
||||
// Set marks so we can scroll to them
|
||||
if (!error_log_row_selected_conn.connected()) { // avoid double-connect
|
||||
error_log_row_selected_conn = treeview->get_selection()->signal_changed().connect(
|
||||
sigc::bind(sigc::bind(sigc::ptr_fun(on_error_log_treeview_row_selected), col_mark_name), this));
|
||||
@@ -1246,11 +1240,6 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
if (iter->generic_name == "scttemp_log") {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = textview->get_buffer();
|
||||
buffer->set_text("\nComplete SCT temperature log:\n\n" + iter->value_string);
|
||||
|
||||
// Make the text monospace (the 3.16+ glade property does not work anymore for some reason).
|
||||
Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
|
||||
tag->property_family() = "Monospace";
|
||||
buffer->apply_tag(tag, buffer->begin(), buffer->end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1396,11 +1385,6 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
if (iter->generic_name == "scterc_log") {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = textview->get_buffer();
|
||||
buffer->set_text("\nComplete SCT Error Recovery Control settings:\n\n" + iter->value_string);
|
||||
|
||||
// Make the text monospace (the 3.16+ glade property does not work anymore for some reason).
|
||||
Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
|
||||
tag->property_family() = "Monospace";
|
||||
buffer->apply_tag(tag, buffer->begin(), buffer->end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1434,11 +1418,6 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
if (iter->generic_name == "selective_selftest_log") {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = textview->get_buffer();
|
||||
buffer->set_text("\nComplete selective self-test log:\n\n" + iter->value_string);
|
||||
|
||||
// Make the text monospace (the 3.16+ glade property does not work anymore for some reason).
|
||||
Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
|
||||
tag->property_family() = "Monospace";
|
||||
buffer->apply_tag(tag, buffer->begin(), buffer->end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1472,11 +1451,6 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
if (iter->generic_name == "sataphy_log") {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = textview->get_buffer();
|
||||
buffer->set_text("\nComplete phy log:\n\n" + iter->value_string);
|
||||
|
||||
// Make the text monospace (the 3.16+ glade property does not work anymore for some reason).
|
||||
Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
|
||||
tag->property_family() = "Monospace";
|
||||
buffer->apply_tag(tag, buffer->begin(), buffer->end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1510,11 +1484,6 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
if (iter->generic_name == "directory_log") {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = textview->get_buffer();
|
||||
buffer->set_text("\nComplete directory log:\n\n" + iter->value_string);
|
||||
|
||||
// Make the text monospace (the 3.16+ glade property does not work anymore for some reason).
|
||||
Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
|
||||
tag->property_family() = "Monospace";
|
||||
buffer->apply_tag(tag, buffer->begin(), buffer->end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
class GscInfoWindow : public AppUIResWidget<GscInfoWindow, true> {
|
||||
public:
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_info_window);
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscInfoWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui);
|
||||
|
||||
/// Virtual destructor
|
||||
|
||||
+13
-80
@@ -15,15 +15,10 @@
|
||||
#include <cstdio> // std::printf
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
#include <gtkmm.h>
|
||||
#include <glib.h> // g_, G*
|
||||
#include <glibmm.h> // set_application_name
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <versionhelpers.h>
|
||||
#endif
|
||||
// #include <iostream>
|
||||
|
||||
#include "hz/hz_config.h" // ENABLE_GLIB, VERSION, DEBUG_BUILD
|
||||
|
||||
@@ -192,26 +187,7 @@ extern "C" {
|
||||
const gchar* message, gpointer user_data)
|
||||
{
|
||||
// log_domain is already printed as part of message.
|
||||
switch(log_level) {
|
||||
case G_LOG_FLAG_RECURSION:
|
||||
case G_LOG_FLAG_FATAL:
|
||||
case G_LOG_LEVEL_ERROR: // fatal
|
||||
case G_LOG_LEVEL_CRITICAL:
|
||||
debug_print_error("gtk", "%s\n", message);
|
||||
break;
|
||||
case G_LOG_LEVEL_WARNING:
|
||||
debug_print_warn("gtk", "%s\n", message);
|
||||
break;
|
||||
case G_LOG_LEVEL_MESSAGE:
|
||||
case G_LOG_LEVEL_INFO:
|
||||
debug_print_info("gtk", "%s\n", message);
|
||||
break;
|
||||
case G_LOG_LEVEL_DEBUG:
|
||||
debug_print_dump("gtk", "%s\n", message);
|
||||
break;
|
||||
case G_LOG_LEVEL_MASK:
|
||||
break;
|
||||
}
|
||||
debug_print_error("gtk", "%s\n", message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,9 +206,7 @@ namespace {
|
||||
arg_scan(TRUE),
|
||||
arg_hide_tabs(TRUE),
|
||||
arg_add_virtual(NULL),
|
||||
arg_add_device(NULL),
|
||||
arg_gdk_scale(std::numeric_limits<double>::quiet_NaN()),
|
||||
arg_gdk_dpi_scale(std::numeric_limits<double>::quiet_NaN())
|
||||
arg_add_device(NULL)
|
||||
{ }
|
||||
|
||||
// Note: Use GLib types here:
|
||||
@@ -242,8 +216,6 @@ namespace {
|
||||
gboolean arg_hide_tabs; ///< if true, hide additional info tabs when smart is disabled. false may help debugging.
|
||||
gchar** arg_add_virtual; ///< load smartctl data from these files as virtual drives
|
||||
gchar** arg_add_device; ///< add these device files manually
|
||||
double arg_gdk_scale; ///< The value of GDK_SCALE environment variable
|
||||
double arg_gdk_dpi_scale; ///< The value of GDK_DPI_SCALE environment variable
|
||||
};
|
||||
|
||||
|
||||
@@ -267,13 +239,6 @@ namespace {
|
||||
"Add this device to device list. The format of the device is \"<device>::<type>::<extra_args>\", where type and extra_args are optional."
|
||||
" This option is useful with --no-scan to list certain drives only. You can specify this option multiple times."
|
||||
" Example: --add-device /dev/sda --add-device /dev/twa0::3ware,2 --add-device '/dev/sdb::::-T permissive'", NULL },
|
||||
#ifndef _WIN32
|
||||
// X11-specific
|
||||
{ "gdk-scale", 'l', 0, G_OPTION_ARG_DOUBLE, &(args.arg_gdk_scale),
|
||||
"The value of GDK_SCALE environment variable (useful when executing with pkexec)", NULL },
|
||||
{ "gdk-dpi-scale", 'l', 0, G_OPTION_ARG_DOUBLE, &(args.arg_gdk_dpi_scale),
|
||||
"The value of GDK_DPI_SCALE environment variable (useful when executing with pkexec)", NULL },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -326,7 +291,7 @@ namespace {
|
||||
std::string warningtext = std::string("\nWarning: GSmartControl");
|
||||
warningtext += " comes with ABSOLUTELY NO WARRANTY.\n";
|
||||
warningtext += "See LICENSE_gsmartcontrol.txt file for details.\n";
|
||||
warningtext += "\nCopyright (C) 2008 - 2022 Alexander Shaduri <ashaduri" "" "@" "" "" "gmail.com>\n\n";
|
||||
warningtext += "\nCopyright (C) 2008 - 2017 Alexander Shaduri <ashaduri" "" "@" "" "" "gmail.com>\n\n";
|
||||
|
||||
std::fprintf(stdout, "%s%s", versiontext.c_str(), warningtext.c_str());
|
||||
}
|
||||
@@ -342,11 +307,8 @@ bool app_init_and_loop(int& argc, char**& argv)
|
||||
// Glib::thread_init();
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string csd_value;
|
||||
if (!hz::env_get_value("GTK_CSD", csd_value)) { // if not set
|
||||
// Disable client-side decorations (enable native windows decorations) under Windows.
|
||||
hz::env_set_value("GTK_CSD", "0");
|
||||
}
|
||||
// Disable client-side decorations (enable native windows decorations) under Windows.
|
||||
hz::env_set_value("GTK_CSD", "0");
|
||||
#endif
|
||||
|
||||
// Glib needs the C locale set to system locale for command line args.
|
||||
@@ -420,21 +382,10 @@ bool app_init_and_loop(int& argc, char**& argv)
|
||||
<< "\thide_tabs: " << args.arg_hide_tabs << "\n"
|
||||
<< "\tscan: " << args.arg_scan << "\n"
|
||||
<< "\targ_add_virtual: " << (load_virtuals_str.empty() ? "[empty]" : load_virtuals_str) << "\n"
|
||||
<< "\targ_add_device: " << (load_devices_str.empty() ? "[empty]" : load_devices_str) << "\n"
|
||||
<< "\targ_gdk_scale: " << args.arg_gdk_scale << "\n"
|
||||
<< "\targ_gdk_dpi_scale: " << args.arg_gdk_dpi_scale << "\n");
|
||||
<< "\targ_add_device: " << (load_devices_str.empty() ? "[empty]" : load_devices_str) << "\n");
|
||||
|
||||
debug_out_dump("app", "LibDebug options:\n" << debug_get_cmd_args_dump());
|
||||
|
||||
#ifndef _WIN32
|
||||
if (args.arg_gdk_scale == args.arg_gdk_scale) { // not NaN
|
||||
hz::env_set_value("GDK_SCALE", hz::number_to_string(args.arg_gdk_scale));
|
||||
}
|
||||
if (args.arg_gdk_dpi_scale == args.arg_gdk_dpi_scale) { // not NaN
|
||||
hz::env_set_value("GDK_DPI_SCALE", hz::number_to_string(args.arg_gdk_dpi_scale));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Load config files
|
||||
app_init_config();
|
||||
@@ -445,8 +396,8 @@ bool app_init_and_loop(int& argc, char**& argv)
|
||||
static const char* const gtkdomains[] = {
|
||||
// no atk or cairo, they don't log. libgnomevfs may be loaded by gtk file chooser.
|
||||
"GLib", "GModule", "GLib-GObject", "GLib-GRegex", "GLib-GIO", "GThread",
|
||||
"Pango", "Gtk", "Gdk", "GdkPixbuf", "libgnomevfs",
|
||||
"glibmm", "giomm", "atkmm", "pangomm", "gdkmm", "gtkmm" };
|
||||
"Pango", "Gtk", "Gdk", "GdkPixbuf", "libglade", "libgnomevfs",
|
||||
"glibmm", "giomm", "atkmm", "pangomm", "gdkmm", "gtkmm", "libglademm" };
|
||||
|
||||
for (unsigned int i = 0; i < G_N_ELEMENTS(gtkdomains); ++i) {
|
||||
g_log_set_handler(gtkdomains[i], GLogLevelFlags(G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL
|
||||
@@ -500,29 +451,11 @@ bool app_init_and_loop(int& argc, char**& argv)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows "Classic" theme is broken under GTK+3's "win32" theme.
|
||||
// Make sure we fall back to Adwaita (which works, but looks non-native)
|
||||
// for platforms which support "Classic" theme - Windows Server and Windows Vista / 7.
|
||||
// Windows 8 / 10 don't support "Classic" so native look is preferred.
|
||||
{
|
||||
Glib::RefPtr<Gtk::Settings> gtk_settings = Gtk::Settings::get_default();
|
||||
if (gtk_settings) {
|
||||
Glib::ustring theme_name = gtk_settings->property_gtk_theme_name().get_value();
|
||||
debug_out_dump("app", "Current GTK theme: " << theme_name << "\n");
|
||||
if (IsWindowsServer() || !IsWindows8OrGreater()) {
|
||||
if (theme_name == "win32") {
|
||||
debug_out_dump("app", "Windows with Classic theme support detected, switching to Adwaita theme.\n");
|
||||
gtk_settings->property_gtk_theme_name().set_value("Adwaita");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set default icon for all windows.
|
||||
// Win32 version has its icon compiled-in, so no need to set it there.
|
||||
#ifndef _WIN32
|
||||
// set default icon for all windows.
|
||||
// set_default_icon_name is available since 2.12 in gtkmm, but since 2.6 in gtk.
|
||||
|
||||
#ifndef _WIN32 // win32 version has its icon compiled-in, so no need to set it there.
|
||||
{
|
||||
// we load it via icontheme to provide multi-size version.
|
||||
|
||||
|
||||
+60
-18
@@ -16,7 +16,6 @@
|
||||
#include "hz/fs_file.h" // hz::File
|
||||
#include "hz/debug.h"
|
||||
#include "hz/scoped_ptr.h"
|
||||
#include "hz/launch_url.h"
|
||||
#include "rconfig/rconfig_mini.h"
|
||||
#include "applib/storage_detector.h"
|
||||
#include "applib/smartctl_parser.h"
|
||||
@@ -30,6 +29,7 @@
|
||||
#include "gsc_init.h" // app_quit()
|
||||
#include "gsc_about_dialog.h"
|
||||
#include "gsc_info_window.h"
|
||||
#include "gsc_help_window.h"
|
||||
#include "gsc_preferences_window.h"
|
||||
#include "gsc_executor_log_window.h"
|
||||
#include "gsc_executor_error_dialog.h" // gsc_executor_error_dialog_show
|
||||
@@ -267,8 +267,10 @@ bool GscMainWindow::create_widgets()
|
||||
" </menu>"
|
||||
|
||||
" <menu action='help_menu'>"
|
||||
" <menuitem action='" APP_ACTION_NAME(action_online_documentation) "' />"
|
||||
" <menuitem action='" APP_ACTION_NAME(action_support) "' />"
|
||||
" <menuitem action='" APP_ACTION_NAME(action_general_help) "' />"
|
||||
" <menuitem action='" APP_ACTION_NAME(action_permission_problems) "' />"
|
||||
" <menuitem action='" APP_ACTION_NAME(action_how_to_enable_smart) "' />"
|
||||
" <menuitem action='" APP_ACTION_NAME(action_report_bug) "' />"
|
||||
" <menuitem action='" APP_ACTION_NAME(action_about) "' />"
|
||||
" </menu>"
|
||||
|
||||
@@ -378,13 +380,21 @@ bool GscMainWindow::create_widgets()
|
||||
|
||||
actiongroup_main->add(Gtk::Action::create("help_menu", "_Help"));
|
||||
|
||||
action = Gtk::Action::create(APP_ACTION_NAME(action_online_documentation), Gtk::Stock::HELP);
|
||||
actiongroup_main->add((action_map[action_online_documentation] = action), Gtk::AccelKey("F1"),
|
||||
sigc::bind(sigc::mem_fun(*this, &self_type::on_action_activated), action_online_documentation));
|
||||
action = Gtk::Action::create(APP_ACTION_NAME(action_general_help), Gtk::Stock::HELP, "A_ll Help Topics");
|
||||
actiongroup_main->add((action_map[action_general_help] = action), Gtk::AccelKey("F1"),
|
||||
sigc::bind(sigc::mem_fun(*this, &self_type::on_action_activated), action_general_help));
|
||||
|
||||
action = Gtk::Action::create(APP_ACTION_NAME(action_support), "Support");
|
||||
actiongroup_main->add((action_map[action_support] = action),
|
||||
sigc::bind(sigc::mem_fun(*this, &self_type::on_action_activated), action_support));
|
||||
action = Gtk::Action::create(APP_ACTION_NAME(action_permission_problems), "Resolving _Permission Problems");
|
||||
actiongroup_main->add((action_map[action_permission_problems] = action),
|
||||
sigc::bind(sigc::mem_fun(*this, &self_type::on_action_activated), action_permission_problems));
|
||||
|
||||
action = Gtk::Action::create(APP_ACTION_NAME(action_how_to_enable_smart), "How to _Enable SMART Permanently");
|
||||
actiongroup_main->add((action_map[action_how_to_enable_smart] = action),
|
||||
sigc::bind(sigc::mem_fun(*this, &self_type::on_action_activated), action_how_to_enable_smart));
|
||||
|
||||
action = Gtk::Action::create(APP_ACTION_NAME(action_report_bug), "_Reporting Bugs");
|
||||
actiongroup_main->add((action_map[action_report_bug] = action),
|
||||
sigc::bind(sigc::mem_fun(*this, &self_type::on_action_activated), action_report_bug));
|
||||
|
||||
action = Gtk::Action::create(APP_ACTION_NAME(action_about), Gtk::Stock::ABOUT);
|
||||
actiongroup_main->add((action_map[action_about] = action),
|
||||
@@ -613,15 +623,51 @@ void GscMainWindow::on_action_activated(GscMainWindow::action_t action_type)
|
||||
break;
|
||||
}
|
||||
|
||||
case action_online_documentation:
|
||||
case action_general_help:
|
||||
{
|
||||
hz::launch_url(gobj(), "https://gsmartcontrol.sourceforge.io/documentation.html");
|
||||
GscHelpWindow* win = GscHelpWindow::create(); // destroyed on close
|
||||
// win->set_transient_for(*this); // for "destroy with parent", always-on-top
|
||||
win->show();
|
||||
while(g_main_context_pending(NULL)) {
|
||||
g_main_context_iteration(NULL, false);
|
||||
}
|
||||
win->set_topic("Begin"); // special mark, top of the text.
|
||||
break;
|
||||
}
|
||||
|
||||
case action_support:
|
||||
case action_permission_problems:
|
||||
{
|
||||
hz::launch_url(gobj(), "https://gsmartcontrol.sourceforge.io/support.html");
|
||||
GscHelpWindow* win = GscHelpWindow::create(); // destroyed on close
|
||||
// win->set_transient_for(*this); // for "destroy with parent", always-on-top
|
||||
win->show();
|
||||
while(g_main_context_pending(NULL)) {
|
||||
g_main_context_iteration(NULL, false);
|
||||
}
|
||||
win->set_topic("Permission Problems");
|
||||
break;
|
||||
}
|
||||
|
||||
case action_how_to_enable_smart:
|
||||
{
|
||||
GscHelpWindow* win = GscHelpWindow::create(); // destroyed on close
|
||||
// win->set_transient_for(*this); // for "destroy with parent", always-on-top
|
||||
win->show();
|
||||
while(g_main_context_pending(NULL)) {
|
||||
g_main_context_iteration(NULL, false);
|
||||
}
|
||||
win->set_topic("Enable SMART Permanently");
|
||||
break;
|
||||
}
|
||||
|
||||
case action_report_bug:
|
||||
{
|
||||
GscHelpWindow* win = GscHelpWindow::create(); // destroyed on close
|
||||
// win->set_transient_for(*this); // for "destroy with parent", always-on-top
|
||||
win->show();
|
||||
while(g_main_context_pending(NULL)) {
|
||||
g_main_context_iteration(NULL, false);
|
||||
}
|
||||
win->set_topic("Reporting Bugs");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -946,7 +992,7 @@ void GscMainWindow::update_status_widgets()
|
||||
std::string model = Glib::Markup::escape_text(drive->get_model_name().empty() ? std::string("Unknown model") : drive->get_model_name());
|
||||
std::string family = Glib::Markup::escape_text(drive->get_family_name().empty() ? "Unknown" : drive->get_family_name());
|
||||
std::string family_fallback = Glib::Markup::escape_text(drive->get_family_name().empty() ? model : drive->get_family_name());
|
||||
std::string drive_letters_str = Glib::Markup::escape_text(drive->format_drive_letters(false));
|
||||
std::string drive_letters_str = Glib::Markup::escape_text(drive->format_drive_letters());
|
||||
|
||||
std::string info_str = device
|
||||
+ (drive_letters_str.empty() ? "" : (" (<b>" + drive_letters_str + "</b>)"))
|
||||
@@ -1203,10 +1249,6 @@ bool GscMainWindow::testing_active() const
|
||||
|
||||
GscInfoWindow* GscMainWindow::show_device_info_window(StorageDeviceRefPtr drive)
|
||||
{
|
||||
if (!drive) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if a test is being run on it, disallow.
|
||||
if (drive->get_test_is_active()) {
|
||||
gui_show_warn_dialog("Please wait until the test is finished on this drive.", this);
|
||||
|
||||
@@ -34,11 +34,11 @@ class GscMainWindow : public AppUIResWidget<GscMainWindow, false> {
|
||||
|
||||
friend class GscMainWindowIconView; // It needs our privates
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_main_window);
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscMainWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui);
|
||||
|
||||
/// Virtual destructor
|
||||
@@ -97,8 +97,10 @@ class GscMainWindow : public AppUIResWidget<GscMainWindow, false> {
|
||||
action_update_drivedb,
|
||||
action_preferences,
|
||||
|
||||
action_online_documentation,
|
||||
action_support,
|
||||
action_general_help,
|
||||
action_permission_problems,
|
||||
action_how_to_enable_smart,
|
||||
action_report_bug,
|
||||
action_about
|
||||
};
|
||||
|
||||
|
||||
+53
-132
@@ -29,7 +29,7 @@
|
||||
|
||||
|
||||
/// The icon view of the main window (shows a drive list).
|
||||
/// Note: The IconView must have a fixed icon width set (e.g. in .ui file).
|
||||
/// Note: The IconView must have a fixed icon width set (e.g. in glade file).
|
||||
/// Otherwise, it doesn't re-compute it when clearing and adding new icons.
|
||||
class GscMainWindowIconView : public Gtk::IconView {
|
||||
public:
|
||||
@@ -47,7 +47,7 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
};
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscMainWindowIconView(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui)
|
||||
: Gtk::IconView(gtkcobj), num_icons(0), main_window(0), empty_view_message(message_none)
|
||||
{
|
||||
@@ -57,20 +57,10 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
columns.add(col_description);
|
||||
|
||||
columns.add(col_pixbuf);
|
||||
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
// For high quality rendering with GDK_SCALE=2
|
||||
this->pack_start(cell_renderer_pixbuf, false);
|
||||
this->set_cell_data_func(cell_renderer_pixbuf,
|
||||
sigc::mem_fun(this, &GscMainWindowIconView::on_cell_data_render));
|
||||
#else
|
||||
this->set_pixbuf_column(col_pixbuf);
|
||||
#endif
|
||||
|
||||
columns.add(col_drive_ptr);
|
||||
|
||||
columns.add(col_populated);
|
||||
|
||||
// create a Tree Model
|
||||
ref_list_model = Gtk::ListStore::create(columns);
|
||||
// ref_list_model->set_sort_column(col_name, Gtk::SORT_ASCENDING);
|
||||
@@ -88,24 +78,18 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
// nothing
|
||||
}
|
||||
|
||||
// Adwaita's drive-harddisk icons are really small at 48, so 64 is better.
|
||||
// Plus, it scales well to 128 and 256 (if using GDK_SCALE).
|
||||
const int icon_size = 64;
|
||||
// Try Gnome icons icons first, they are usually more consistent with Gnome desktop
|
||||
// (this should work only if gnome-settings-daemon is running, so no harm on other desktops).
|
||||
// The problem with stock gtk icons is that they are not available in 48x48 size, so
|
||||
// confirm all sizes manually.
|
||||
|
||||
// Try XDG version first
|
||||
#if APP_GTKMM_CHECK_VERSION(3, 10, 0)
|
||||
try {
|
||||
hd_icon = default_icon_theme->load_icon("drive-harddisk", icon_size, get_scale_factor(), Gtk::IconLookupFlags(0));
|
||||
} catch (...) { } // ignore exceptions
|
||||
#endif
|
||||
if (!hd_icon) {
|
||||
// Before gtk 3.10 it was called gtk-harddisk.
|
||||
try {
|
||||
hd_icon = default_icon_theme->load_icon("gtk-harddisk", icon_size, Gtk::IconLookupFlags(0));
|
||||
} catch (...) { } // ignore exceptions
|
||||
}
|
||||
if (!hd_icon) {
|
||||
// Still no luck, use bundled ones.
|
||||
if (app_gtkmm_icon_theme_has_icon(default_icon_theme, "gnome-dev-harddisk", 48))
|
||||
hd_icon = default_icon_theme->load_icon("gnome-dev-harddisk", 48, Gtk::IconLookupFlags(0));
|
||||
|
||||
if (!hd_icon && app_gtkmm_icon_theme_has_icon(default_icon_theme, "gtk-harddisk", 48))
|
||||
hd_icon = default_icon_theme->load_icon("gtk-harddisk", 48, Gtk::IconLookupFlags(0));
|
||||
|
||||
if (!hd_icon) { // still no luck, use bundled ones.
|
||||
std::string icon_file = hz::data_file_find("icon_hdd.png");
|
||||
if (!icon_file.empty()) {
|
||||
try {
|
||||
@@ -114,20 +98,18 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
}
|
||||
}
|
||||
|
||||
// Try XDG version first
|
||||
#if APP_GTKMM_CHECK_VERSION(3, 10, 0)
|
||||
try {
|
||||
cddvd_icon = default_icon_theme->load_icon("media-optical", icon_size, get_scale_factor(), Gtk::IconLookupFlags(0));
|
||||
} catch (...) { } // ignore exceptions
|
||||
#endif
|
||||
if (!cddvd_icon) {
|
||||
// Before gtk 3.10 it was called gtk-cdrom.
|
||||
try {
|
||||
cddvd_icon = default_icon_theme->load_icon("gtk-cdrom", icon_size, Gtk::IconLookupFlags(0));
|
||||
} catch (...) { } // ignore exceptions
|
||||
}
|
||||
if (!cddvd_icon) {
|
||||
// Still no luck, use bundled ones.
|
||||
// last resort. gtk has gtk-harddisk built-in. it may not be the right size, but what else can we do?
|
||||
if (!hd_icon && default_icon_theme)
|
||||
hd_icon = default_icon_theme->load_icon("gtk-harddisk", 48, Gtk::IconLookupFlags(0));
|
||||
|
||||
|
||||
if (app_gtkmm_icon_theme_has_icon(default_icon_theme, "gnome-dev-cdrom", 48))
|
||||
cddvd_icon = default_icon_theme->load_icon("gnome-dev-cdrom", 48, Gtk::IconLookupFlags(0));
|
||||
|
||||
if (!cddvd_icon && app_gtkmm_icon_theme_has_icon(default_icon_theme, "gtk-cdrom", 48))
|
||||
cddvd_icon = default_icon_theme->load_icon("gtk-cdrom", 48, Gtk::IconLookupFlags(0));
|
||||
|
||||
if (!cddvd_icon) { // still no luck, use bundled ones.
|
||||
std::string icon_file = hz::data_file_find("icon_cddvd.png");
|
||||
if (!icon_file.empty()) {
|
||||
try {
|
||||
@@ -136,6 +118,10 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
}
|
||||
}
|
||||
|
||||
if (!cddvd_icon && default_icon_theme)
|
||||
cddvd_icon = default_icon_theme->load_icon("gtk-cdrom", 48, Gtk::IconLookupFlags(0));
|
||||
|
||||
|
||||
this->signal_item_activated().connect(sigc::mem_fun(*this,
|
||||
&self_type::on_iconview_item_activated) );
|
||||
|
||||
@@ -203,42 +189,6 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
|
||||
|
||||
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
/// Cell data renderer (needed for high quality icons in GDK_SCALE=2).
|
||||
/// We have to use Cairo surfaces, because pixbufs are scaled by GtkIconView.
|
||||
void on_cell_data_render(const Gtk::TreeModel::const_iterator& iter)
|
||||
{
|
||||
Gtk::TreeRow row = *iter;
|
||||
if (!row[col_populated]) { // protect against rendering incomplete model entry
|
||||
return;
|
||||
}
|
||||
|
||||
Glib::RefPtr<Gdk::Pixbuf> pixbuf = row[col_pixbuf];
|
||||
if (!pixbuf) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Gtkmm property_surface() doesn't work, so use plain C.
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=788513
|
||||
// Also, Gtkmm doesn't have gdk_cairo_surface_create_from_pixbuf() wrapper.
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=788533
|
||||
|
||||
// Cairo::Format format = Cairo::FORMAT_ARGB32;
|
||||
// if (pixbuf->get_n_channels() == 3) {
|
||||
// format = Cairo::FORMAT_RGB24;
|
||||
// }
|
||||
// Cairo::RefPtr<Cairo::Surface> surface = get_window()->create_similar_image_surface(
|
||||
// format, pixbuf->get_width(), pixbuf->get_height(), get_scale_factor());
|
||||
// cell_renderer_pixbuf.property_surface().set_value(surface);
|
||||
|
||||
// gdk_cairo_surface_create_from_pixbuf() (and create_similar_image_surface()) from gtk 3.10.
|
||||
cairo_surface_t* surface = gdk_cairo_surface_create_from_pixbuf(pixbuf->gobj(), get_scale_factor(), get_window()->gobj());
|
||||
g_object_set(G_OBJECT(cell_renderer_pixbuf.gobj()), "surface", surface, NULL);
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// Add a drive entry to the icon view
|
||||
void add_entry(StorageDeviceRefPtr drive, bool scroll_to_it = false)
|
||||
{
|
||||
@@ -250,8 +200,6 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
|
||||
this->decorate_entry(row);
|
||||
|
||||
row[col_populated] = true; // triggers rendering
|
||||
|
||||
drive->signal_changed.connect(sigc::mem_fun(this, &GscMainWindowIconView::on_drive_changed));
|
||||
|
||||
if (scroll_to_it) {
|
||||
@@ -290,29 +238,16 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
void decorate_entry(Gtk::TreeModel::Row& row)
|
||||
{
|
||||
StorageDeviceRefPtr drive = row[col_drive_ptr];
|
||||
if (!drive) {
|
||||
return;
|
||||
}
|
||||
|
||||
// it needs this space to be symmetric (why?);
|
||||
std::string name; // = "<big>" + drive->get_device_with_type() + " </big>\n";
|
||||
Glib::ustring drive_letters = Glib::Markup::escape_text(drive->format_drive_letters(false));
|
||||
if (drive_letters.empty()) {
|
||||
drive_letters = "not mounted";
|
||||
}
|
||||
Glib::ustring drive_letters_with_volname = Glib::Markup::escape_text(drive->format_drive_letters(true));
|
||||
if (drive_letters_with_volname.empty()) {
|
||||
drive_letters_with_volname = "not mounted";
|
||||
}
|
||||
|
||||
// note: if this wraps, it becomes left-aligned in gtk <= 2.10.
|
||||
name += (drive->get_model_name().empty() ? Glib::ustring("Unknown model") : Glib::Markup::escape_text(drive->get_model_name()));
|
||||
if (rconfig::get_data<bool>("gui/icons_show_device_name")) {
|
||||
if (!drive->get_is_virtual()) {
|
||||
name += "\n" + Glib::Markup::escape_text(drive->get_device_with_type());
|
||||
#ifdef _WIN32
|
||||
name += " (" + drive_letters + ")";
|
||||
#endif
|
||||
name += " (" + Glib::Markup::escape_text(drive->format_drive_letters()) + ")";
|
||||
} else if (!drive->get_virtual_filename().empty()) {
|
||||
name += "\n" + Glib::Markup::escape_text(drive->get_virtual_filename());
|
||||
}
|
||||
@@ -339,11 +274,9 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
} else {
|
||||
tooltip_strs.push_back("Device: <b>" + Glib::Markup::escape_text(drive->get_device_with_type()) + "</b>");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
tooltip_strs.push_back("Drive letters: <b>" + drive_letters_with_volname + "</b>");
|
||||
#endif
|
||||
|
||||
if (!drive->format_drive_letters().empty()) {
|
||||
tooltip_strs.push_back("Drive letters: <b>" + Glib::Markup::escape_text(drive->format_drive_letters()) + "</b>");
|
||||
}
|
||||
if (!drive->get_serial_number().empty()) {
|
||||
tooltip_strs.push_back("Serial number: <b>" + Glib::Markup::escape_text(drive->get_serial_number()) + "</b>");
|
||||
}
|
||||
@@ -369,24 +302,22 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
|
||||
StorageProperty health_prop = drive->get_health_property();
|
||||
if (health_prop.warning != StorageProperty::warning_none && health_prop.generic_name == "overall_health") {
|
||||
if (icon) {
|
||||
icon = icon->copy(); // work on a copy
|
||||
if (icon->get_colorspace() == Gdk::COLORSPACE_RGB && icon->get_bits_per_sample() == 8) {
|
||||
int n_channels = icon->get_n_channels();
|
||||
int icon_width = icon->get_width();
|
||||
int icon_height = icon->get_height();
|
||||
int rowstride = icon->get_rowstride();
|
||||
guint8* pixels = icon->get_pixels();
|
||||
icon = icon->copy(); // work on a copy
|
||||
if (icon->get_colorspace() == Gdk::COLORSPACE_RGB && icon->get_bits_per_sample() == 8) {
|
||||
int n_channels = icon->get_n_channels();
|
||||
int icon_width = icon->get_width();
|
||||
int icon_height = icon->get_height();
|
||||
int rowstride = icon->get_rowstride();
|
||||
guint8* pixels = icon->get_pixels();
|
||||
|
||||
guint8* p = 0;
|
||||
for (int y = 0; y < icon_height; ++y) {
|
||||
for (int x = 0; x < icon_width; ++x) {
|
||||
p = pixels + y * rowstride + x * n_channels;
|
||||
uint8_t avg = static_cast<uint8_t>(std::floor((p[0] * 0.30) + (p[1] * 0.59) + (p[2] * 0.11) + 0.001 + 0.5));
|
||||
p[0] = avg; // R
|
||||
p[1] = 0; // G
|
||||
p[2] = 0; // B
|
||||
}
|
||||
guint8* p = 0;
|
||||
for (int y = 0; y < icon_height; ++y) {
|
||||
for (int x = 0; x < icon_width; ++x) {
|
||||
p = pixels + y * rowstride + x * n_channels;
|
||||
uint8_t avg = static_cast<uint8_t>(std::floor((p[0] * 0.30) + (p[1] * 0.59) + (p[2] * 0.11) + 0.001 + 0.5));
|
||||
p[0] = avg; // R
|
||||
p[1] = 0; // G
|
||||
p[2] = 0; // B
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,11 +418,8 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
} else { // enable drives menu, set proper smart toggles
|
||||
Gtk::TreePath model_path = *(this->get_selected_items().begin());
|
||||
Gtk::TreeModel::Row row = *(ref_list_model->get_iter(model_path));
|
||||
if (!row[col_populated]) { // protect against using incomplete model entry
|
||||
return;
|
||||
}
|
||||
|
||||
StorageDeviceRefPtr drive = row[col_drive_ptr];
|
||||
|
||||
main_window->set_drive_menu_status(drive);
|
||||
}
|
||||
}
|
||||
@@ -505,11 +433,8 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
return;
|
||||
|
||||
Gtk::TreeModel::Row row = *(ref_list_model->get_iter(model_path));
|
||||
if (!row[col_populated]) { // protect against using incomplete model entry
|
||||
return;
|
||||
}
|
||||
|
||||
StorageDeviceRefPtr drive = row[col_drive_ptr];
|
||||
|
||||
main_window->show_device_info_window(drive);
|
||||
}
|
||||
|
||||
@@ -556,11 +481,9 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
this->unselect_all(); // unselect on empty area right-click
|
||||
}
|
||||
|
||||
if (drive) {
|
||||
Gtk::Menu* menu = main_window->get_popup_menu(drive);
|
||||
if (menu)
|
||||
menu->popup(event_button->button, event_button->time);
|
||||
}
|
||||
Gtk::Menu* menu = main_window->get_popup_menu(drive);
|
||||
if (menu)
|
||||
menu->popup(event_button->button, event_button->time);
|
||||
|
||||
return true; // stop handling
|
||||
}
|
||||
@@ -584,13 +507,11 @@ class GscMainWindowIconView : public Gtk::IconView {
|
||||
private:
|
||||
|
||||
Gtk::TreeModel::ColumnRecord columns; ///< Model columns
|
||||
Gtk::CellRendererPixbuf cell_renderer_pixbuf; ///< Cell renderer for icons.
|
||||
|
||||
Gtk::TreeModelColumn<std::string> col_name; ///< Model column
|
||||
Gtk::TreeModelColumn<Glib::ustring> col_description; ///< Model column
|
||||
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > col_pixbuf; ///< Model column
|
||||
Gtk::TreeModelColumn<StorageDeviceRefPtr> col_drive_ptr; ///< Model column
|
||||
Gtk::TreeModelColumn<bool> col_populated; ///< Model column, indicates whether the model entry has been fully populated.
|
||||
|
||||
Glib::RefPtr<Gtk::ListStore> ref_list_model; ///< The icon view model
|
||||
unsigned int num_icons; ///< Track the number of icons, because liststore makes it difficult to count them.
|
||||
|
||||
@@ -33,7 +33,7 @@ class GscPreferencesDeviceOptionsTreeView : public Gtk::TreeView {
|
||||
typedef GscPreferencesDeviceOptionsTreeView self_type; ///< Self type, needed for CONNECT_VIRTUAL
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscPreferencesDeviceOptionsTreeView(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui)
|
||||
: Gtk::TreeView(gtkcobj), preferences_window(0)
|
||||
{
|
||||
|
||||
@@ -29,11 +29,11 @@ class GscMainWindow; // declared in gsc_main_window.h
|
||||
class GscPreferencesWindow : public AppUIResWidget<GscPreferencesWindow, true> {
|
||||
public:
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_preferences_window);
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscPreferencesWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui);
|
||||
|
||||
/// Virtual destructor
|
||||
|
||||
@@ -38,14 +38,14 @@ template<class InstanceSwitch>
|
||||
class GscTextWindow : public AppUIResWidget<GscTextWindow<InstanceSwitch>, InstanceSwitch::multi_instance> {
|
||||
public:
|
||||
|
||||
// name of ui file without a .ui extension and quotes
|
||||
// name of glade/ui file without a .glade/.ui extension and quotes
|
||||
APP_UI_RES_DATA_INIT(gsc_text_window);
|
||||
|
||||
/// Self type, needed for GtkBuilder, not inherited from parent because of templates
|
||||
/// Self type, needed for glade, not inherited from parent because of templates
|
||||
typedef GscTextWindow<InstanceSwitch> self_type;
|
||||
|
||||
|
||||
/// Constructor, GtkBuilder needs this.
|
||||
/// Constructor, gtkbuilder/glade needs this.
|
||||
GscTextWindow(typename Gtk::Window::BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui)
|
||||
: AppUIResWidget<GscTextWindow<InstanceSwitch>, InstanceSwitch::multi_instance>(gtkcobj, ref_ui)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
|
||||
gsmartcontrol ICON "gsmartcontrol.ico"
|
||||
|
||||
// Embed manifest in exe
|
||||
1 24 "gsmartcontrol.exe.manifest"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 0,0,0,0
|
||||
PRODUCTVERSION 0,0,0,0
|
||||
@@ -17,7 +14,7 @@ BEGIN
|
||||
VALUE "FileDescription", "GSmartControl - Hard disk drive and SSD health inspection tool"
|
||||
VALUE "FileVersion", "@VERSION@"
|
||||
VALUE "InternalName", "gsmartcontrol.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2008 - 2022 Alexander Shaduri"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2008 - 2017 Alexander Shaduri"
|
||||
VALUE "OriginalFilename", "gsmartcontrol.exe"
|
||||
VALUE "ProductName", "GSmartControl"
|
||||
VALUE "ProductVersion", "@VERSION@"
|
||||
|
||||
@@ -18,12 +18,10 @@
|
||||
</ms_asmv2:security>
|
||||
</ms_asmv2:trustInfo>
|
||||
|
||||
<!-- GTK3 applications aren't quite dpi-aware with win32 theme, among other
|
||||
visual issues.
|
||||
On the other hand, HiDPI Adwaita works (it also looks slightly like win11 theme), so we prefer that. -->
|
||||
<!-- GTK3 applications aren't quite dpi-aware -->
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<dpiAware>true</dpiAware>
|
||||
<dpiAware>false</dpiAware>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace internal {
|
||||
|
||||
inline int process_signal_send(process_id_t process_handle, signal_t sig)
|
||||
{
|
||||
if (process_handle == 0) {
|
||||
if (process_handle <= 0) {
|
||||
errno = ESRCH; // The pid or process group does not exist.
|
||||
return -1;
|
||||
}
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ Configuration macros: HZ_ENABLE_COMPILED_RES_DATA (0 | 1).
|
||||
// Compiled-in buffers:
|
||||
|
||||
/// Declare that we have a binary chunk res_name.
|
||||
/// (You may use this e.g. with GtkBuilder xml contents, putting it into your window class).
|
||||
/// (You may use this e.g. with glade xml contents, putting it into your window class).
|
||||
#define HZ_RES_DATA_COMPILED_INIT_NAMED(res_name, dummy, class_name) \
|
||||
struct class_name { \
|
||||
class_name() \
|
||||
|
||||
+6
-5
@@ -1,9 +1,9 @@
|
||||
|
||||
# Disable implicit suffix rules for these extensions.
|
||||
# The problem is that make sees the .ui.cpp files
|
||||
# with their .ui prerequisites, and decides to rebuild the
|
||||
# (already existing) .ui files by using .ui.cpp files.
|
||||
# Implicit rules are to blame, so disable them for .ui.
|
||||
# The problem is that make sees the .glade.cpp or .ui.cpp files
|
||||
# with their .glade prerequisites, and decides to rebuild the
|
||||
# (already existing) .glade files by using .glade.cpp files.
|
||||
# Implicit rules are to blame, so disable them for .glade.
|
||||
SUFFIXES = .ui .txt
|
||||
|
||||
AM_CPPFLAGS =
|
||||
@@ -18,11 +18,12 @@ libres_a_SOURCES =
|
||||
EXTRA_libres_a_SOURCES = gsc_about_dialog.ui.cpp \
|
||||
gsc_add_device_window.ui.cpp \
|
||||
gsc_executor_log_window.ui.cpp \
|
||||
gsc_help_window.ui.cpp \
|
||||
gsc_info_window.ui.cpp \
|
||||
gsc_main_window.ui.cpp \
|
||||
gsc_preferences_window.ui.cpp \
|
||||
gsc_text_window.ui.cpp \
|
||||
AUTHORS.txt.cpp LICENSE_gsmartcontrol.txt.cpp
|
||||
AUTHORS.txt.cpp LICENSE_gsmartcontrol.txt.cpp README.txt.cpp
|
||||
|
||||
# list all intermediate files here (.tmp_ui files are cleaned automatically by make, but it won't hurt)
|
||||
mostlyclean-local:
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.4"/>
|
||||
<object class="GtkWindow" id="gsc_help_window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Help - GSmartControl</property>
|
||||
<property name="default_width">900</property>
|
||||
<property name="default_height">650</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkPaned" id="hpaned1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="position">200</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Topics</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="topics_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Topics</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="content_textview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="is_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">word</property>
|
||||
<property name="left_margin">5</property>
|
||||
<property name="right_margin">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="window_close_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -5,8 +5,8 @@
|
||||
<object class="GtkWindow" id="gsc_main_window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">GSmartControl</property>
|
||||
<property name="default_width">560</property>
|
||||
<property name="default_height">450</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">540</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
@@ -136,9 +136,9 @@
|
||||
<property name="is_focus">True</property>
|
||||
<property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="margin">10</property>
|
||||
<property name="item_width">250</property>
|
||||
<property name="item_width">130</property>
|
||||
<property name="spacing">3</property>
|
||||
<property name="row_spacing">20</property>
|
||||
<property name="row_spacing">8</property>
|
||||
<property name="column_spacing">5</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
<object class="GtkEntry" id="smartctl_options_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Global parameters for smartctl. These parameters will be used every time the program invokes smartctl. Must be shell-escaped.</property>
|
||||
<property name="tooltip_text" translatable="yes">Global parameters for smartctl. These parameters will be used every time the progam invokes smartctl. Must be shell-escaped.</property>
|
||||
<property name="activates_default">True</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_activatable">False</property>
|
||||
@@ -239,7 +239,7 @@
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Global parameters for smartctl. These parameters will be used every time the program invokes smartctl. Must be shell-escaped.</property>
|
||||
<property name="tooltip_text" translatable="yes">Global parameters for smartctl. These parameters will be used every time the progam invokes smartctl. Must be shell-escaped.</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Smartctl parameters:</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
||||
Reference in New Issue
Block a user