Compare commits

..
1 Commits
Author SHA1 Message Date
Alexander Shaduri aec8ba4d12 Tagged 1.1.0. 2017-09-07 15:08:03 +00:00
63 changed files with 1148 additions and 1955 deletions
-3
View File
@@ -1,3 +0,0 @@
# Make sure github recognizes header files as C++, not C.
*.h linguist-language=C++
-171
View File
@@ -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*.*
-88
View File
@@ -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
View File
@@ -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
*~
+18
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
svn propset svn:ignore -F .svnignore.txt .
+58 -104
View File
@@ -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)
-37
View File
@@ -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
View File
@@ -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).
+6 -2
View File
@@ -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)
-982
View File
@@ -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
]])
-4
View File
@@ -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
View File
@@ -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
+2 -8
View File
@@ -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
+2 -2
View File
@@ -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>
-3
View File
@@ -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

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

+2 -2
View File
@@ -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).
+3 -5
View File
@@ -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
View File
@@ -1 +1 @@
9
5
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
+18
View File
@@ -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).
+5
View File
@@ -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);
+11 -10
View File
@@ -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);
+1 -1
View File
@@ -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);
+1 -6
View File
@@ -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).
+1 -1
View File
@@ -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
-5
View File
@@ -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;
+20 -42
View File
@@ -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),
+6 -9
View File
@@ -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);
+4 -5
View File
@@ -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
+3 -37
View File
@@ -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();
}
-3
View File
@@ -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).
+1 -1
View File
@@ -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")) {
+3 -3
View File
@@ -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();
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+223
View File
@@ -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]);
}
}
/// @}
+79
View File
@@ -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
View File
@@ -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());
}
}
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+6 -4
View File
@@ -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
View File
@@ -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.
+1 -1
View File
@@ -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)
{
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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 -4
View File
@@ -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@"
+2 -4
View File
@@ -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>
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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:
+164
View File
@@ -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>
+4 -4
View File
@@ -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>
+2 -2
View File
@@ -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>
View File