Merge pull request #48 from ZoiteChat/gtk3-prep

gtk3/many minor fixes and updates.
This commit is contained in:
deepend-tildeclub
2026-02-16 19:52:05 -07:00
committed by GitHub
86 changed files with 6524 additions and 1369 deletions

View File

@@ -29,9 +29,11 @@ jobs:
build-essential pkg-config meson ninja-build cmake \ build-essential pkg-config meson ninja-build cmake \
gettext \ gettext \
libcanberra-dev libdbus-glib-1-dev libglib2.0-dev \ libcanberra-dev libdbus-glib-1-dev libglib2.0-dev \
libgtk2.0-dev libgtk-3-dev \ libgtk-3-dev \
libwayland-client0 libwayland-cursor0 libwayland-egl1 \
libxkbcommon0 \
libgtk-3-bin libglib2.0-bin shared-mime-info gsettings-desktop-schemas \ libgtk-3-bin libglib2.0-bin shared-mime-info gsettings-desktop-schemas \
libluajit-5.1-dev libpci-dev libperl-dev libssl-dev \ libluajit-5.1-dev libpci-dev libperl-dev libssl-dev libayatana-appindicator3-dev \
python3-dev python3-cffi mono-devel desktop-file-utils \ python3-dev python3-cffi mono-devel desktop-file-utils \
patchelf file curl patchelf file curl
@@ -41,6 +43,7 @@ jobs:
rm -rf build rm -rf build
meson setup build \ meson setup build \
--prefix=/usr \ --prefix=/usr \
-Dgtk3=true \
-Dtext-frontend=true \ -Dtext-frontend=true \
-Dwith-perl=perl \ -Dwith-perl=perl \
-Dwith-python=python3 \ -Dwith-python=python3 \
@@ -74,11 +77,9 @@ jobs:
chmod +x linuxdeploy-plugin-gtk chmod +x linuxdeploy-plugin-gtk
export PATH="${PWD}:${PATH}" export PATH="${PWD}:${PATH}"
# Bundle CA certificates into the AppDir
install -Dm644 /etc/ssl/certs/ca-certificates.crt \ install -Dm644 /etc/ssl/certs/ca-certificates.crt \
AppDir/etc/ssl/certs/ca-certificates.crt AppDir/etc/ssl/certs/ca-certificates.crt
# Custom AppRun: preserve typical AppDir runtime paths AND force CA bundle
cat > AppRun <<'EOF' cat > AppRun <<'EOF'
#!/bin/sh #!/bin/sh
set -eu set -eu
@@ -99,15 +100,26 @@ jobs:
export GIO_EXTRA_MODULES="$APPDIR/usr/lib/gio/modules${GIO_EXTRA_MODULES:+:$GIO_EXTRA_MODULES}" export GIO_EXTRA_MODULES="$APPDIR/usr/lib/gio/modules${GIO_EXTRA_MODULES:+:$GIO_EXTRA_MODULES}"
fi fi
# OpenSSL trust store override (fixes “unable to get local issuer certificate (20)”) # OpenSSL trust store override
export SSL_CERT_FILE="${SSL_CERT_FILE:-$APPDIR/etc/ssl/certs/ca-certificates.crt}" export SSL_CERT_FILE="${SSL_CERT_FILE:-$APPDIR/etc/ssl/certs/ca-certificates.crt}"
export SSL_CERT_DIR="${SSL_CERT_DIR:-$APPDIR/etc/ssl/certs}" export SSL_CERT_DIR="${SSL_CERT_DIR:-$APPDIR/etc/ssl/certs}"
export CURL_CA_BUNDLE="${CURL_CA_BUNDLE:-$SSL_CERT_FILE}" export CURL_CA_BUNDLE="${CURL_CA_BUNDLE:-$SSL_CERT_FILE}"
# Prefer Wayland if the session provides it, but keep X11 fallback.
# Don't override if the user already set GDK_BACKEND explicitly.
if [ -z "${GDK_BACKEND:-}" ]; then
if [ -n "${WAYLAND_DISPLAY:-}" ] || [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
export GDK_BACKEND="wayland,x11"
else
export GDK_BACKEND="x11"
fi
fi
exec "$APPDIR/usr/bin/zoitechat" "$@" exec "$APPDIR/usr/bin/zoitechat" "$@"
EOF EOF
chmod +x AppRun chmod +x AppRun
VERSION="$(git describe --tags --always)" VERSION="$(git describe --tags --always)"
./linuxdeploy-x86_64.AppImage \ ./linuxdeploy-x86_64.AppImage \

View File

@@ -13,47 +13,36 @@ jobs:
image: debian:bookworm image: debian:bookworm
steps: steps:
- name: Install base tooling (git + deps) - name: Install packaging tooling and build dependencies
run: | run: |
set -eux set -eux
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
apt-get update apt-get update
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
git ca-certificates \ git ca-certificates \
build-essential pkg-config meson ninja-build cmake \ build-essential dpkg-dev debhelper fakeroot \
gettext \ pkg-config meson ninja-build \
libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk2.0-dev \ gettext iso-codes \
libluajit-5.1-dev libpci-dev libperl-dev libssl-dev \ libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk-3-dev libayatana-appindicator3-dev \
python3-dev python3-cffi mono-devel desktop-file-utils liblua5.3-dev libpci-dev libperl-dev libssl-dev \
python3-dev python3-cffi desktop-file-utils
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
submodules: true submodules: true
- name: Configure - name: Build Debian packages
run: | run: |
set -eux set -eux
rm -rf build dpkg-buildpackage -us -uc -b
meson setup build \
-Dtext-frontend=true \
-Dauto_features=enabled
# If configure fails, show the project's actual option names in the log.
- name: Show Meson options (on failure)
if: failure()
run: |
set -eux
meson configure build || true
- name: Build - name: Collect Debian artifacts
run: | run: |
set -eux set -eux
ninja -C build mkdir -p artifacts
cp -v ../*.deb ../*.changes ../*.buildinfo artifacts/
- name: Test - name: Upload Debian artifacts
run: | uses: actions/upload-artifact@v4
set -eux with:
ninja -C build test name: zoitechat-debian-packages
path: artifacts/*
- name: Install
run: |
set -eux
ninja -C build install

View File

@@ -32,7 +32,7 @@ jobs:
git \ git \
meson ninja pkgconf gmake \ meson ninja pkgconf gmake \
gettext-tools \ gettext-tools \
glib2 gtk+2 dbus-glib libcanberra \ glib2 gtk+3 dbus-glib libcanberra \
luajit mono libgdiplus openssl luajit mono libgdiplus openssl
work="$(mktemp -d /tmp/zoitechat.XXXXXX)" work="$(mktemp -d /tmp/zoitechat.XXXXXX)"
@@ -45,6 +45,7 @@ jobs:
meson setup build \ meson setup build \
--prefix=/usr/local \ --prefix=/usr/local \
-Dtext-frontend=true \ -Dtext-frontend=true \
-Dgtk3=true \
-Dplugin=false \ -Dplugin=false \
-Dauto_features=enabled -Dauto_features=enabled

60
.github/workflows/solus-eopkg-build.yml vendored Normal file
View File

@@ -0,0 +1,60 @@
name: Solus eopkg build
on:
workflow_dispatch:
inputs:
package_yml:
description: "Path to Solus package.yml for ypkg build"
required: false
default: "packaging/solus/package.yml"
solus_image:
description: "Solus container image"
required: false
default: "ghcr.io/getsolus/solus:latest"
push:
branches:
- main
- master
jobs:
build-eopkg:
runs-on: ubuntu-latest
env:
SOLUS_IMAGE: ${{ inputs.solus_image || 'ghcr.io/getsolus/solus:latest' }}
PACKAGE_YML: ${{ inputs.package_yml || 'packaging/solus/package.yml' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build eopkg package in Solus container
run: |
if [ ! -f "$PACKAGE_YML" ]; then
echo "Expected Solus packaging file at $PACKAGE_YML" >&2
echo "Available package.yml files:" >&2
find . -name "package.yml" -print >&2 || true
echo "Add a package.yml (ypkg) file or update the workflow input PACKAGE_YML." >&2
exit 1
fi
docker pull "$SOLUS_IMAGE"
docker run --rm \
-v "$PWD":/workspace \
-w /workspace \
-e PACKAGE_YML="$PACKAGE_YML" \
"$SOLUS_IMAGE" \
sh -lc '
set -euo pipefail
eopkg update-repo -y
eopkg install -y ypkg git
ypkg build "$PACKAGE_YML"
mkdir -p /workspace/artifacts
find . -maxdepth 3 -name "*.eopkg" -type f -exec cp -v {} /workspace/artifacts/ \;
'
- name: Upload eopkg artifacts
uses: actions/upload-artifact@v4
with:
name: solus-eopkg
path: artifacts/*.eopkg
if-no-files-found: error

View File

@@ -10,7 +10,7 @@ on:
jobs: jobs:
windows_build: windows_build:
runs-on: windows-2019 runs-on: windows-2022
permissions: permissions:
contents: read contents: read
@@ -20,13 +20,8 @@ jobs:
strategy: strategy:
matrix: matrix:
platform: [x64, win32] platform: [x64]
arch: [x64, x86] arch: [x64]
exclude:
- platform: x64
arch: x86
- platform: win32
arch: x64
fail-fast: false fail-fast: false
steps: steps:
@@ -39,16 +34,16 @@ jobs:
- name: Install Dependencies - name: Install Dependencies
run: | run: |
New-Item -Name "deps" -ItemType "Directory" New-Item -Name "deps" -ItemType "Directory" -Force | Out-Null
Invoke-WebRequest http://files.jrsoftware.org/is/5/innosetup-5.5.9-unicode.exe -OutFile deps\innosetup-unicode.exe Invoke-WebRequest https://files.jrsoftware.org/is/6/innosetup-6.7.0.exe -OutFile deps\innosetup-unicode.exe
& deps\innosetup-unicode.exe /VERYSILENT | Out-Null & deps\innosetup-unicode.exe /VERYSILENT | Out-Null
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe
& deps\idpsetup.exe /VERYSILENT & deps\idpsetup.exe /VERYSILENT
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z Invoke-WebRequest https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.18.0-pre1/GTK3_Gvsbuild_zoitechat-2.18.0-pre1_${{ matrix.platform }}.7z -OutFile deps\gtk-${{ matrix.arch }}.7z
& 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk & 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk\x64\release
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z
& 7z.exe x deps\gendef.7z -oC:\gtk-build & 7z.exe x deps\gendef.7z -oC:\gtk-build
@@ -76,7 +71,7 @@ jobs:
- name: Build - name: Build
run: | run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat"
set "PYTHON_DIR=C:\gtk-build\python-3.14.2\${{ matrix.platform }}" set "PYTHON_DIR=C:\gtk-build\python-3.14.2\${{ matrix.platform }}"
if not exist "%PYTHON_DIR%\libs\python314.lib" ( if not exist "%PYTHON_DIR%\libs\python314.lib" (
@@ -93,7 +88,7 @@ jobs:
- name: Preparing Artifacts - name: Preparing Artifacts
run: | run: |
move ..\zoitechat-build\${{ matrix.platform }}\ZoiteChat*.exe .\ move ..\zoitechat-build\${{ matrix.platform }}\ZoiteChat-*.exe .\
move ..\zoitechat-build .\ move ..\zoitechat-build .\
shell: cmd shell: cmd
@@ -102,7 +97,7 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: Installer ${{ matrix.arch }} name: Installer ${{ matrix.arch }}
path: ZoiteChat*.exe path: ZoiteChat-*.exe
- name: Attest Installer (Artifact Attestation) - name: Attest Installer (Artifact Attestation)
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}

View File

@@ -1,6 +1,15 @@
ZoiteChat ChangeLog ZoiteChat ChangeLog
================= =================
2.18.0-pre1 (2026-02-16)
------------------------
- Switched Debian packaging/builds to GTK 3 (Build-Depends, Meson flags, and package metadata).
- Added Debian package split install manifests so files are assigned to the correct binary packages.
- Fixed Debian packaging coverage for the man page and MIME XML to avoid unassigned-file (dh_missing) failures.
- Updated Debian CI packaging workflow and artifact upload paths for actions/upload-artifact@v4 compatibility.
- Improved GTK3 font consistency by applying the configured input font to channel tree and user list theming paths.
2.17.4 (2026-02-03) 2.17.4 (2026-02-03)
------------------- -------------------

View File

@@ -25,6 +25,18 @@
<id>zoitechat.desktop</id> <id>zoitechat.desktop</id>
</provides> </provides>
<releases> <releases>
<release date="2026-02-16" version="2.18.0-pre1">
<description>
<p>Packaging and GTK3 improvements:</p>
<ul>
<li>Switched Debian package builds to GTK 3.</li>
<li>Added split-package install manifests for Debian outputs.</li>
<li>Fixed unassigned Debian package files (man page and MIME XML).</li>
<li>Updated Debian CI artifact upload handling for GitHub Actions v4.</li>
<li>Improved GTK3 channel/user list font consistency when applying theme updates.</li>
</ul>
</description>
</release>
<release date="2026-02-03" version="2.17.4"> <release date="2026-02-03" version="2.17.4">
<description> <description>
<p>Fixes and minor features:</p> <p>Fixes and minor features:</p>

View File

@@ -9,7 +9,7 @@ Terminal=false
Type=Application Type=Application
Categories=GTK;Network;IRCClient; Categories=GTK;Network;IRCClient;
StartupNotify=true StartupNotify=true
StartupWMClass=Zoitechat StartupWMClass=net.zoite.Zoitechat
X-GNOME-UsesNotifications=true X-GNOME-UsesNotifications=true
MimeType=x-scheme-handler/irc;x-scheme-handler/ircs;application/x-zoitechat-theme;application/x-hexchat-theme; MimeType=x-scheme-handler/irc;x-scheme-handler/ircs;application/x-zoitechat-theme;application/x-hexchat-theme;
Actions=SafeMode; Actions=SafeMode;

20
debian/changelog vendored
View File

@@ -1,3 +1,23 @@
zoitechat (2.18.0~pre1-1) unstable; urgency=medium
* New upstream pre-release 2.18.0~pre1.
* Debian packaging updates in this branch:
- switch package builds to GTK 3 and pass -Dgtk3=true to Meson.
- add/install split-package manifests for generated binary packages.
- include manpage and MIME package XML in package installs.
- adjust CI artifact staging/upload paths for actions/upload-artifact@v4.
-- ZoiteChat Maintainers <zoitechat@users.noreply.github.com> Sun, 16 Feb 2026 00:00:00 +0000
zoitechat (2.17.0-1) unstable; urgency=medium
* Switch Debian build to GTK 3 packaging:
- replace libgtk2.0-dev with libgtk-3-dev in Build-Depends.
- pass -Dgtk3=true to Meson during package builds.
- update package description to explicitly reference GTK 3.
-- ZoiteChat Maintainers <zoitechat@users.noreply.github.com> Sun, 16 Feb 2026 00:00:00 +0000
zoitechat (2.17.0-0) stable; urgency=medium zoitechat (2.17.0-0) stable; urgency=medium
* Initial ZoiteChat packaging (forked from HexChat's Debian packaging). * Initial ZoiteChat packaging (forked from HexChat's Debian packaging).

6
debian/control vendored
View File

@@ -9,7 +9,7 @@ Build-Depends:
libcanberra-dev, libcanberra-dev,
libdbus-glib-1-dev, libdbus-glib-1-dev,
libglib2.0-dev, libglib2.0-dev,
libgtk2.0-dev, libgtk-3-dev,
liblua5.3-dev, liblua5.3-dev,
libpci-dev, libpci-dev,
libperl-dev, libperl-dev,
@@ -39,8 +39,8 @@ Suggests:
zoitechat-python3, zoitechat-python3,
zoitechat-otr, zoitechat-otr,
unifont unifont
Description: IRC client for GNOME (fork of HexChat 2.17.0 base) Description: IRC client for GNOME (fork of HexChat 2.18.0-pre1 base)
ZoiteChat is a graphical IRC client with a GTK+ GUI. Features include Python, ZoiteChat is a graphical IRC client with a GTK 3 GUI. Features include Python,
Perl and Lua scripting support, a plugin API, multiple server/channel Perl and Lua scripting support, a plugin API, multiple server/channel
windows, spell checking, multiple authentication methods including SASL, and windows, spell checking, multiple authentication methods including SASL, and
customizable notifications. For more information on IRC, see customizable notifications. For more information on IRC, see

11
debian/rules vendored
View File

@@ -7,8 +7,17 @@ export DH_VERBOSE=1
override_dh_auto_configure: override_dh_auto_configure:
dh_auto_configure -- \ dh_auto_configure -- \
-Dgtk3=true \
-Dinstall-plugin-metainfo=false \ -Dinstall-plugin-metainfo=false \
-Dwith-lua=lua53 -Dwith-lua=lua53
override_dh_installchangelogs: override_dh_installchangelogs:
dh_installchangelogs debian/changelog.txt install -m0755 -d \
debian/zoitechat/usr/share/doc/zoitechat \
debian/zoitechat-common/usr/share/doc/zoitechat-common \
debian/zoitechat-perl/usr/share/doc/zoitechat-perl \
debian/zoitechat-python3/usr/share/doc/zoitechat-python3 \
debian/zoitechat-lua/usr/share/doc/zoitechat-lua \
debian/zoitechat-plugins/usr/share/doc/zoitechat-plugins \
debian/zoitechat-dev/usr/share/doc/zoitechat-dev
dh_installchangelogs changelog.rst

7
debian/zoitechat-common.install vendored Normal file
View File

@@ -0,0 +1,7 @@
usr/share/applications/net.zoite.Zoitechat.desktop
usr/share/dbus-1/services/org.zoitechat.service.service
usr/share/icons/hicolor/48x48/apps/net.zoite.Zoitechat.png
usr/share/icons/hicolor/scalable/apps/net.zoite.Zoitechat.svg
usr/share/locale/*/LC_MESSAGES/zoitechat.mo
usr/share/metainfo/net.zoite.Zoitechat.appdata.xml
usr/share/mime/packages/net.zoite.Zoitechat.mime.xml

2
debian/zoitechat-dev.install vendored Normal file
View File

@@ -0,0 +1,2 @@
usr/include/zoitechat-plugin.h
usr/lib/*/pkgconfig/zoitechat-plugin.pc

1
debian/zoitechat-lua.install vendored Normal file
View File

@@ -0,0 +1 @@
usr/lib/*/zoitechat/plugins/lua.so

1
debian/zoitechat-perl.install vendored Normal file
View File

@@ -0,0 +1 @@
usr/lib/*/zoitechat/plugins/perl.so

3
debian/zoitechat-plugins.install vendored Normal file
View File

@@ -0,0 +1,3 @@
usr/lib/*/zoitechat/plugins/checksum.so
usr/lib/*/zoitechat/plugins/fishlim.so
usr/lib/*/zoitechat/plugins/sysinfo.so

4
debian/zoitechat-python3.install vendored Normal file
View File

@@ -0,0 +1,4 @@
usr/lib/*/zoitechat/plugins/python.so
usr/lib/*/zoitechat/python/_zoitechat.py
usr/lib/*/zoitechat/python/xchat.py
usr/lib/*/zoitechat/python/zoitechat.py

View File

@@ -1,3 +1,2 @@
usr/bin/zoitechat usr/bin/zoitechat
usr/share/applications usr/share/man/man1/zoitechat.1
usr/share/metainfo/net.zoite.Zoitechat.appdata.xml

View File

@@ -7,7 +7,7 @@
"command": "zoitechat", "command": "zoitechat",
"finish-args": [ "finish-args": [
"--share=ipc", "--share=ipc",
"--socket=x11", "--socket=wayland",
"--share=network", "--share=network",
"--socket=pulseaudio", "--socket=pulseaudio",
"--filesystem=xdg-download", "--filesystem=xdg-download",
@@ -28,11 +28,10 @@
} }
}, },
"modules": [ "modules": [
"shared-modules/gtk2/gtk2.json",
"shared-modules/gtk2/gtk2-common-themes.json",
"shared-modules/dbus-glib/dbus-glib.json", "shared-modules/dbus-glib/dbus-glib.json",
"shared-modules/lua5.3/lua-5.3.5.json", "shared-modules/lua5.3/lua-5.3.5.json",
"shared-modules/libcanberra/libcanberra.json", "shared-modules/libcanberra/libcanberra.json",
"shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json",
"python3-cffi.json", "python3-cffi.json",
{ {
"name": "lgi", "name": "lgi",
@@ -43,13 +42,14 @@
"url": "https://github.com/pavouk/lgi.git", "url": "https://github.com/pavouk/lgi.git",
"commit": "95418635aa8151a516d43166227ea2b9d4c4403f" "commit": "95418635aa8151a516d43166227ea2b9d4c4403f"
} }
] ]
}, },
{ {
"name": "zoitechat", "name": "zoitechat",
"buildsystem": "meson", "buildsystem": "meson",
"config-opts": [ "config-opts": [
"--buildtype=release", "--buildtype=release",
"-Dgtk3=true",
"-Ddbus-service-use-appid=true", "-Ddbus-service-use-appid=true",
"-Dwith-perl=false", "-Dwith-perl=false",
"-Dwith-python=false", "-Dwith-python=false",

View File

@@ -1,6 +1,6 @@
project('zoitechat', 'c', project('zoitechat', 'c',
version: '2.17.4', version: '2.18.0-pre1',
meson_version: '>= 0.47.0', meson_version: '>= 0.55.0',
default_options: [ default_options: [
'c_std=c17', 'c_std=c17',
'buildtype=debugoptimized', 'buildtype=debugoptimized',
@@ -145,7 +145,7 @@ if not (host_machine.system() == 'windows' and get_option('debug'))
test_ldflags += '-Wl,--dynamicbase' test_ldflags += '-Wl,--dynamicbase'
endif endif
foreach ldflag : test_ldflags foreach ldflag : test_ldflags
if meson.version().version_compare('>= 0.46.0') if meson.version().version_compare('>= 0.55.0')
has_arg = cc.has_link_argument(ldflag) has_arg = cc.has_link_argument(ldflag)
else else
has_arg = cc.has_argument(ldflag) has_arg = cc.has_argument(ldflag)
@@ -168,7 +168,7 @@ if cc.get_id() != 'msvc'
meson.add_install_script('meson_post_install.py') meson.add_install_script('meson_post_install.py')
endif endif
if meson.version().version_compare('>= 0.53.0') if meson.version().version_compare('>= 0.55.0')
summary({ summary({
'prefix': get_option('prefix'), 'prefix': get_option('prefix'),
'bindir': get_option('bindir'), 'bindir': get_option('bindir'),

View File

@@ -2,6 +2,9 @@
option('gtk-frontend', type: 'boolean', option('gtk-frontend', type: 'boolean',
description: 'Main graphical interface' description: 'Main graphical interface'
) )
option('gtk3', type: 'boolean', value: false,
description: 'Build GTK frontend against GTK 3'
)
option('text-frontend', type: 'boolean', value: false, option('text-frontend', type: 'boolean', value: false,
description: 'Text interface (not generally useful)' description: 'Text interface (not generally useful)'
) )

View File

@@ -0,0 +1,34 @@
name : zoitechat
version : 2.18.0-pre1
release : 1
source :
- https://github.com/ZoiteChat/zoitechat/archive/refs/tags/zoitechat-2.18.0-pre1.tar.gz : 77d787cf00abd533326440eab01ca077c21cdfd2eb56807fc21d6fb70f34ada6
homepage : https://zoitechat.zoite.net/
license : GPL-2.0-only
component : network.irc
summary : HexChat-based IRC client
description: |
ZoiteChat is a HexChat-based IRC client for Windows and UNIX-like systems.
builddeps :
- pkgconfig(glib-2.0)
- pkgconfig(gmodule-2.0)
- pkgconfig(gtk+-3.0)
- pkgconfig(ayatana-appindicator3-0.1)
- pkgconfig(dbus-glib-1)
- pkgconfig(libcanberra)
- pkgconfig(openssl)
- pkgconfig(iso-codes)
- meson
- ninja
- pkgconfig
- gcc
- gettext
setup : |
%meson_configure \
-Dgtk-frontend=true \
-Dgtk3=true \
-Dinstall-appdata=true
build : |
%ninja_build
install : |
%ninja_install

View File

@@ -30,7 +30,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<ModuleDefinitionFile>checksum.def</ModuleDefinitionFile> <ModuleDefinitionFile>checksum.def</ModuleDefinitionFile>
@@ -41,7 +41,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<ModuleDefinitionFile>checksum.def</ModuleDefinitionFile> <ModuleDefinitionFile>checksum.def</ModuleDefinitionFile>

View File

@@ -30,7 +30,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile> <ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>
@@ -41,7 +41,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile> <ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>

View File

@@ -51,4 +51,4 @@
<ClCompile Include="lua.c" /> <ClCompile Include="lua.c" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project> </Project>

View File

@@ -29,7 +29,10 @@
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;Py_NO_LINK_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UndefinePreprocessorDefinitions>_DEBUG;Py_DEBUG;Py_REF_DEBUG;Py_TRACE_REFS;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
<AdditionalOptions>/U_DEBUG /UPy_DEBUG /UPy_REF_DEBUG /UPy_TRACE_REFS %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -41,9 +44,12 @@
<Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\zoitechat-plugin.h python.py "$(IntDir)python.c"</Command> <Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\zoitechat-plugin.h python.py "$(IntDir)python.c"</Command>
</PreBuildEvent> </PreBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;Py_NO_LINK_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UndefinePreprocessorDefinitions>_DEBUG;Py_DEBUG;Py_REF_DEBUG;Py_TRACE_REFS;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
<AdditionalOptions>/U_DEBUG /UPy_DEBUG /UPy_REF_DEBUG /UPy_TRACE_REFS %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -67,4 +73,8 @@
<ClCompile Include="$(IntDir)python.c" /> <ClCompile Include="$(IntDir)python.c" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project> </Project>

View File

@@ -273,3 +273,25 @@ sysinfo_backend_get_network(void)
{ {
return NULL; return NULL;
} }
static const char *sysinfo_detect_toolkit(void)
{
#if defined(HAVE_GTK3)
return "GTK3";
#elif defined(HAVE_GTK2)
return "GTK2";
#elif defined(HAVE_GTK)
return "GTK";
#else
return NULL;
#endif
}
char *sysinfo_backend_get_ui(void)
{
const char *toolkit = sysinfo_detect_toolkit();
if (toolkit)
return g_strdup_printf("%s / Quartz", toolkit);
return g_strdup("Quartz");
}

View File

@@ -30,4 +30,10 @@ char *sysinfo_backend_get_sound(void);
char *sysinfo_backend_get_uptime(void); char *sysinfo_backend_get_uptime(void);
char *sysinfo_backend_get_network(void); char *sysinfo_backend_get_network(void);
/*
* Short description of the UI/toolkit + display backend.
* Examples: "GTK3 / Wayland", "GTK2 / X11", "Windows / GTK3".
*/
char *sysinfo_backend_get_ui(void);
#endif #endif

View File

@@ -41,7 +41,7 @@ static zoitechat_plugin *ph;
static char name[] = "Sysinfo"; static char name[] = "Sysinfo";
static char desc[] = "Display info about your hardware and OS"; static char desc[] = "Display info about your hardware and OS";
static char version[] = "1.0"; static char version[] = "1.0";
static char sysinfo_help[] = "SysInfo Usage:\n /SYSINFO [-e|-o] [CLIENT|OS|CPU|RAM|DISK|VGA|SOUND|ETHERNET|UPTIME], print various details about your system or print a summary without arguments\n /SYSINFO SET <variable>\n"; static char sysinfo_help[] = "SysInfo Usage:\n /SYSINFO [-e|-o] [CLIENT|UI|OS|CPU|RAM|DISK|VGA|SOUND|ETHERNET|UPTIME], print various details about your system or print a summary without arguments\n /SYSINFO SET <variable>\n";
typedef struct typedef struct
{ {
@@ -54,11 +54,22 @@ typedef struct
static char * static char *
get_client (void) get_client (void)
{ {
return g_strdup_printf ("ZoiteChat %s", zoitechat_get_info(ph, "version")); char *ui = sysinfo_backend_get_ui();
const char *ver = zoitechat_get_info(ph, "version");
char *out;
if (ui != NULL && *ui != '\0')
out = g_strdup_printf ("ZoiteChat %s (%s)", ver, ui);
else
out = g_strdup_printf ("ZoiteChat %s", ver);
g_free (ui);
return out;
} }
static hwinfo hwinfos[] = { static hwinfo hwinfos[] = {
{"client", "Client", get_client}, {"client", "Client", get_client},
{"ui", "UI", sysinfo_backend_get_ui},
{"os", "OS", sysinfo_backend_get_os}, {"os", "OS", sysinfo_backend_get_os},
{"cpu", "CPU", sysinfo_backend_get_cpu}, {"cpu", "CPU", sysinfo_backend_get_cpu},
{"memory", "Memory", sysinfo_backend_get_memory}, {"memory", "Memory", sysinfo_backend_get_memory},
@@ -235,7 +246,8 @@ zoitechat_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name, char
zoitechat_hook_command (ph, "SYSINFO", ZOITECHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL); zoitechat_hook_command (ph, "SYSINFO", ZOITECHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL);
zoitechat_command (ph, "MENU ADD \"Window/Send System Info\" \"SYSINFO\""); /* Match the classic label from HexChat so people can actually find it. */
zoitechat_command (ph, "MENU ADD \"Window/Display System Info\" \"SYSINFO\"");
zoitechat_printf (ph, _("%s plugin loaded\n"), name); zoitechat_printf (ph, _("%s plugin loaded\n"), name);
return 1; return 1;
} }
@@ -243,6 +255,8 @@ zoitechat_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name, char
int int
zoitechat_plugin_deinit (void) zoitechat_plugin_deinit (void)
{ {
/* Keep both in case older builds used a different label. */
zoitechat_command (ph, "MENU DEL \"Window/Send System Info\"");
zoitechat_command (ph, "MENU DEL \"Window/Display System Info\""); zoitechat_command (ph, "MENU DEL \"Window/Display System Info\"");
zoitechat_printf (ph, _("%s plugin unloaded\n"), name); zoitechat_printf (ph, _("%s plugin unloaded\n"), name);
return 1; return 1;

View File

@@ -31,7 +31,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -44,7 +44,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(ZoiteChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -68,4 +68,4 @@
<ClInclude Include="sysinfo.h" /> <ClInclude Include="sysinfo.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project> </Project>

View File

@@ -18,6 +18,10 @@
*/ */
#include <glib.h> #include <glib.h>
#if defined(HAVE_GTK3) || defined(HAVE_GTK2) || defined(HAVE_GTK)
#include <gdk/gdk.h>
#endif
#include "parse.h" #include "parse.h"
#include "match.h" #include "match.h"
#include "sysinfo.h" #include "sysinfo.h"
@@ -168,3 +172,86 @@ char *sysinfo_backend_get_network(void)
return g_strdup (ethernet_card); return g_strdup (ethernet_card);
} }
static const char *sysinfo_detect_toolkit(void)
{
#if defined(HAVE_GTK3)
return "GTK3";
#elif defined(HAVE_GTK2)
return "GTK2";
#elif defined(HAVE_GTK)
return "GTK";
#else
return NULL;
#endif
}
static const char *sysinfo_detect_display_backend(void)
{
const char *backend = NULL;
const char *gdk_backend = g_getenv("GDK_BACKEND");
const char *session = g_getenv("XDG_SESSION_TYPE");
const gboolean session_wayland = session && g_ascii_strcasecmp(session, "wayland") == 0;
/* Best-effort: ask GDK what it actually opened, if available. */
#if defined(HAVE_GTK3) || defined(HAVE_GTK2) || defined(HAVE_GTK)
{
GdkDisplay *display = gdk_display_get_default();
if (display)
{
const char *type_name = G_OBJECT_TYPE_NAME(display);
if (type_name)
{
if (g_strrstr(type_name, "Wayland"))
backend = "Wayland";
else if (g_strrstr(type_name, "X11"))
backend = "X11";
}
}
}
#endif
/* Next best: honor explicit backend preference. */
if (!backend && gdk_backend)
{
if (g_strrstr(gdk_backend, "wayland"))
backend = "Wayland";
else if (g_strrstr(gdk_backend, "x11"))
backend = "X11";
}
/* Last resort: infer from common env vars. */
if (!backend)
{
const gboolean has_wayland = g_getenv("WAYLAND_DISPLAY") != NULL;
const gboolean has_x11 = g_getenv("DISPLAY") != NULL;
if (has_wayland && !has_x11)
backend = "Wayland";
else if (has_x11 && !has_wayland)
backend = "X11";
else if (session_wayland)
backend = "Wayland";
else
backend = NULL;
}
/* If we're using X11 inside a Wayland session, call it what it is. */
if (backend && g_strcmp0(backend, "X11") == 0 && session_wayland)
return "XWayland";
return backend;
}
char *sysinfo_backend_get_ui(void)
{
const char *toolkit = sysinfo_detect_toolkit();
const char *display = sysinfo_detect_display_backend();
if (toolkit && display)
return g_strdup_printf("%s / %s", toolkit, display);
if (toolkit)
return g_strdup(toolkit);
if (display)
return g_strdup(display);
return NULL;
}

View File

@@ -103,3 +103,30 @@ static char *get_memory_info (void)
return sysinfo_format_memory (meminfo.ullTotalPhys, meminfo.ullAvailPhys); return sysinfo_format_memory (meminfo.ullTotalPhys, meminfo.ullAvailPhys);
} }
static const char *sysinfo_detect_toolkit(void)
{
#if defined(HAVE_GTK3)
return "GTK3";
#elif defined(HAVE_GTK2)
return "GTK2";
#elif defined(HAVE_GTK)
return "GTK";
#else
return NULL;
#endif
}
char *
sysinfo_backend_get_ui (void)
{
const char *toolkit = sysinfo_detect_toolkit();
/* On Windows we don't have X11/Wayland. Keep it simple. */
if (toolkit)
{
return g_strdup_printf ("Windows / %s", toolkit);
}
return g_strdup ("Windows");
}

View File

@@ -39,7 +39,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<ModuleDefinitionFile>winamp.def</ModuleDefinitionFile> <ModuleDefinitionFile>winamp.def</ModuleDefinitionFile>

View File

@@ -99,13 +99,13 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> <DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@@ -116,8 +116,8 @@
SET SOLUTIONDIR=$(SolutionDir)..\ SET SOLUTIONDIR=$(SolutionDir)..\
"$(Python3Path)\python.exe" $(ProjectDir)make-te.py "$(ProjectDir)textevents.in" "$(ZoiteChatLib)textevents.h" "$(ZoiteChatLib)textenums.h" "$(Python3Path)\python.exe" $(ProjectDir)make-te.py "$(ProjectDir)textevents.in" "$(ZoiteChatLib)textevents.h" "$(ZoiteChatLib)textenums.h"
powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\config.h.tt" "$(ZoiteChatLib)config.h" powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\config.h.tt" "$(ZoiteChatLib)config.h"
"$(Python3Path)\python.exe" "$(DepsRoot)\bin\glib-genmarshal" --prefix=_zoitechat_marshal --header "$(ProjectDir)marshalers.list" --output "$(ZoiteChatLib)marshal.h" $(GlibGenMarshal) --prefix=_zoitechat_marshal --header "$(ProjectDir)marshalers.list" --output "$(ZoiteChatLib)marshal.h"
"$(Python3Path)\python.exe" "$(DepsRoot)\bin\glib-genmarshal" --prefix=_zoitechat_marshal --body "$(ProjectDir)marshalers.list" --output "$(ZoiteChatLib)marshal.c" $(GlibGenMarshal) --prefix=_zoitechat_marshal --body "$(ProjectDir)marshalers.list" --output "$(ZoiteChatLib)marshal.c"
]]></Command> ]]></Command>
</PreBuildEvent> </PreBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>

View File

@@ -40,14 +40,11 @@ static GList *contexts = NULL;
static GHashTable *clients = NULL; static GHashTable *clients = NULL;
static DBusGConnection *connection; static DBusGConnection *connection;
typedef struct RemoteObject RemoteObject; G_DECLARE_FINAL_TYPE (RemoteObject, remote_object, REMOTE, OBJECT, GObject)
typedef struct RemoteObjectClass RemoteObjectClass;
GType Remote_object_get_type (void); struct _RemoteObject
struct RemoteObject
{ {
GObject parent; GObject parent_instance;
guint last_hook_id; guint last_hook_id;
guint last_list_id; guint last_list_id;
@@ -59,11 +56,6 @@ struct RemoteObject
void *handle; void *handle;
}; };
struct RemoteObjectClass
{
GObjectClass parent;
};
typedef struct typedef struct
{ {
guint id; guint id;
@@ -89,12 +81,6 @@ enum
static guint signals[LAST_SIGNAL] = { 0 }; static guint signals[LAST_SIGNAL] = { 0 };
#define REMOTE_TYPE_OBJECT (remote_object_get_type ())
#define REMOTE_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), REMOTE_TYPE_OBJECT, RemoteObject))
#define REMOTE_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), REMOTE_TYPE_OBJECT, RemoteObjectClass))
#define REMOTE_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), REMOTE_TYPE_OBJECT))
#define REMOTE_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), REMOTE_TYPE_OBJECT))
#define REMOTE_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), REMOTE_TYPE_OBJECT, RemoteObjectClass))
#define REMOTE_OBJECT_ERROR (remote_object_error_quark ()) #define REMOTE_OBJECT_ERROR (remote_object_error_quark ())
#define REMOTE_TYPE_ERROR (remote_object_error_get_type ()) #define REMOTE_TYPE_ERROR (remote_object_error_get_type ())
@@ -376,7 +362,7 @@ remote_object_connect (RemoteObject *obj,
} }
g_snprintf(count_buffer, sizeof(count_buffer), "%u", count++); g_snprintf(count_buffer, sizeof(count_buffer), "%u", count++);
path = g_build_filename (DBUS_OBJECT_PATH, count_buffer, NULL); path = g_build_filename (DBUS_OBJECT_PATH, count_buffer, NULL);
remote_object = g_object_new (REMOTE_TYPE_OBJECT, NULL); remote_object = g_object_new (remote_object_get_type (), NULL);
remote_object->dbus_path = path; remote_object->dbus_path = path;
remote_object->filename = g_path_get_basename (filename); remote_object->filename = g_path_get_basename (filename);
remote_object->handle = zoitechat_plugingui_add (ph, remote_object->handle = zoitechat_plugingui_add (ph,
@@ -891,8 +877,8 @@ init_dbus (void)
guint request_name_result; guint request_name_result;
GError *error = NULL; GError *error = NULL;
dbus_g_object_type_install_info (REMOTE_TYPE_OBJECT, dbus_g_object_type_install_info (remote_object_get_type (),
&dbus_glib_remote_object_object_info); &dbus_glib_remote_object_object_info);
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (connection == NULL) { if (connection == NULL) {
@@ -930,7 +916,7 @@ init_dbus (void)
G_CALLBACK (name_owner_changed), G_CALLBACK (name_owner_changed),
NULL, NULL); NULL, NULL);
remote = g_object_new (REMOTE_TYPE_OBJECT, NULL); remote = g_object_new (remote_object_get_type (), NULL);
dbus_g_connection_register_g_object (connection, dbus_g_connection_register_g_object (connection,
DBUS_OBJECT_PATH"/Remote", DBUS_OBJECT_PATH"/Remote",
G_OBJECT (remote)); G_OBJECT (remote));

View File

@@ -229,7 +229,15 @@ static char *query_wmi (QueryWmiType type)
query = SysAllocString (L"SELECT Name FROM Win32_VideoController"); query = SysAllocString (L"SELECT Name FROM Win32_VideoController");
break; break;
case QUERY_WMI_HDD: case QUERY_WMI_HDD:
query = SysAllocString (L"SELECT Name, Capacity, FreeSpace FROM Win32_Volume"); /*
* Query local fixed logical disks only.
*
* Win32_Volume can cause Windows to probe additional network-backed
* providers (for example Plan9/WSL providers), which may trigger RPC
* failures in debugger sessions. Restricting this to fixed logical disks
* avoids those probes while still providing useful local disk stats.
*/
query = SysAllocString (L"SELECT Name, Size, FreeSpace FROM Win32_LogicalDisk WHERE DriveType = 3");
break; break;
default: default:
goto release_queryLanguageName; goto release_queryLanguageName;
@@ -465,7 +473,7 @@ static char *read_hdd_info (IWbemClassObject *object)
VariantClear (&name_variant); VariantClear (&name_variant);
hr = object->lpVtbl->Get (object, L"Capacity", 0, &capacity_variant, NULL, NULL); hr = object->lpVtbl->Get (object, L"Size", 0, &capacity_variant, NULL, NULL);
if (FAILED (hr)) if (FAILED (hr))
{ {
return NULL; return NULL;
@@ -580,7 +588,16 @@ static char *zoitechat_strdup_printf (const char *format, ...)
va_start (args, format); va_start (args, format);
va_copy (args_copy, args); va_copy (args_copy, args);
/*
* MSVC's debug CRT treats vsnprintf(NULL, 0, ...) as an invalid parameter,
* which triggers a fatal runtime exception via ucrtbased.dll. Use
* _vscprintf() to determine required output length on that toolchain.
*/
#ifdef _MSC_VER
length = _vscprintf (format, args_copy);
#else
length = vsnprintf (NULL, 0, format, args_copy); length = vsnprintf (NULL, 0, format, args_copy);
#endif
va_end (args_copy); va_end (args_copy);
if (length < 0) if (length < 0)

View File

@@ -185,6 +185,14 @@ waitline (int sok, char *buf, int bufsize, int use_recv)
{ {
int i = 0; int i = 0;
if (bufsize <= 0)
return -1;
#ifdef WIN32
if (!use_recv && _get_osfhandle (sok) == -1)
return -1;
#endif
while (1) while (1)
{ {
if (use_recv) if (use_recv)

View File

@@ -137,7 +137,11 @@ ascii_open (void)
if (table_pos[0] == '\n' || i == 0) if (table_pos[0] == '\n' || i == 0)
{ {
table_pos++; table_pos++;
#if HAVE_GTK3
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
#elif !HAVE_GTK3
hbox = gtk_hbox_new (0, 0); hbox = gtk_hbox_new (0, 0);
#endif
gtk_container_add (GTK_CONTAINER (vbox), hbox); gtk_container_add (GTK_CONTAINER (vbox), hbox);
gtk_widget_show (hbox); gtk_widget_show (hbox);
i++; i++;

View File

@@ -37,6 +37,17 @@
#include "maingui.h" #include "maingui.h"
#include "banlist.h" #include "banlist.h"
#if HAVE_GTK3
#define ICON_BANLIST_REMOVE "list-remove"
#define ICON_BANLIST_CLEAR "edit-clear"
#define ICON_BANLIST_REFRESH "view-refresh"
#endif
#if !HAVE_GTK3
#define ICON_BANLIST_REMOVE GTK_STOCK_REMOVE
#define ICON_BANLIST_CLEAR GTK_STOCK_CLEAR
#define ICON_BANLIST_REFRESH GTK_STOCK_REFRESH
#endif
/* /*
* These supports_* routines set capable, readable, writable bits */ * These supports_* routines set capable, readable, writable bits */
static void supports_bans (banlist_info *, int); static void supports_bans (banlist_info *, int);
@@ -772,6 +783,19 @@ banlist_closegui (GtkWidget *wid, banlist_info *banl)
} }
} }
static GtkWidget *
banlist_table_new (void)
{
GtkWidget *table = gtkutil_grid_new (1, MODE_CT, FALSE);
#if HAVE_GTK3
gtk_grid_set_column_spacing (GTK_GRID (table), 16);
#else
gtk_table_set_col_spacings (GTK_TABLE (table), 16);
#endif
return table;
}
void void
banlist_opengui (struct session *sess) banlist_opengui (struct session *sess)
{ {
@@ -818,8 +842,7 @@ banlist_opengui (struct session *sess)
/* create banlist view */ /* create banlist view */
banl->treeview = banlist_treeview_new (vbox, banl); banl->treeview = banlist_treeview_new (vbox, banl);
table = gtk_table_new (1, MODE_CT, FALSE); table = banlist_table_new ();
gtk_table_set_col_spacings (GTK_TABLE (table), 16);
gtk_box_pack_start (GTK_BOX (vbox), table, 0, 0, 0); gtk_box_pack_start (GTK_BOX (vbox), table, 0, 0, 0);
for (i = 0; i < MODE_CT; i++) for (i = 0; i < MODE_CT; i++)
@@ -830,23 +853,29 @@ banlist_opengui (struct session *sess)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (banl->checkboxes[i]), (banl->checked & 1<<i? TRUE: FALSE)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (banl->checkboxes[i]), (banl->checked & 1<<i? TRUE: FALSE));
g_signal_connect (G_OBJECT (banl->checkboxes[i]), "toggled", g_signal_connect (G_OBJECT (banl->checkboxes[i]), "toggled",
G_CALLBACK (banlist_toggle), banl); G_CALLBACK (banlist_toggle), banl);
gtk_table_attach (GTK_TABLE (table), banl->checkboxes[i], i+1, i+2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtkutil_grid_attach (table, banl->checkboxes[i], i + 1, i + 2, 0, 1,
GTKUTIL_ATTACH_FILL, GTKUTIL_ATTACH_FILL, 0, 0);
} }
#if HAVE_GTK3
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
bbox = gtk_hbutton_box_new (); bbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (bbox), 5); gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 0); gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 0);
gtk_widget_show (bbox); gtk_widget_show (bbox);
banl->but_remove = gtkutil_button (bbox, GTK_STOCK_REMOVE, 0, banlist_unban, banl, banl->but_remove = gtkutil_button (bbox, ICON_BANLIST_REMOVE, 0, banlist_unban, banl,
_("Remove")); _("Remove"));
banl->but_crop = gtkutil_button (bbox, GTK_STOCK_REMOVE, 0, banlist_crop, banl, banl->but_crop = gtkutil_button (bbox, ICON_BANLIST_REMOVE, 0, banlist_crop, banl,
_("Crop")); _("Crop"));
banl->but_clear = gtkutil_button (bbox, GTK_STOCK_CLEAR, 0, banlist_clear, banl, banl->but_clear = gtkutil_button (bbox, ICON_BANLIST_CLEAR, 0, banlist_clear, banl,
_("Clear")); _("Clear"));
banl->but_refresh = gtkutil_button (bbox, GTK_STOCK_REFRESH, 0, banlist_refresh, banl, _("Refresh")); banl->but_refresh = gtkutil_button (bbox, ICON_BANLIST_REFRESH, 0, banlist_refresh, banl, _("Refresh"));
banlist_do_refresh (banl); banlist_do_refresh (banl);

View File

@@ -45,6 +45,21 @@
#include "custom-list.h" #include "custom-list.h"
#if HAVE_GTK3
#define ICON_CHANLIST_JOIN "go-jump"
#define ICON_CHANLIST_COPY "edit-copy"
#define ICON_CHANLIST_FIND "edit-find"
#define ICON_CHANLIST_REFRESH "view-refresh"
#define ICON_CHANLIST_SAVE "document-save-as"
#endif
#if !HAVE_GTK3
#define ICON_CHANLIST_JOIN GTK_STOCK_JUMP_TO
#define ICON_CHANLIST_COPY GTK_STOCK_COPY
#define ICON_CHANLIST_FIND GTK_STOCK_FIND
#define ICON_CHANLIST_REFRESH GTK_STOCK_REFRESH
#define ICON_CHANLIST_SAVE GTK_STOCK_SAVE_AS
#endif
enum enum
{ {
COL_CHANNEL, COL_CHANNEL,
@@ -68,6 +83,102 @@ chanlistrow;
#define GET_MODEL(xserv) (gtk_tree_view_get_model(GTK_TREE_VIEW(xserv->gui->chanlist_list))) #define GET_MODEL(xserv) (gtk_tree_view_get_model(GTK_TREE_VIEW(xserv->gui->chanlist_list)))
static void
chanlist_set_label_alignment (GtkWidget *widget)
{
#if HAVE_GTK3
gtk_widget_set_halign (widget, GTK_ALIGN_START);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
#endif
}
#if HAVE_GTK3
static void
chanlist_grid_attach (GtkWidget *grid, GtkWidget *child,
gint column, gint row,
gint width, gint height,
gboolean hexpand, gboolean vexpand,
GtkAlign halign, GtkAlign valign)
{
gtk_widget_set_hexpand (child, hexpand);
gtk_widget_set_vexpand (child, vexpand);
gtk_widget_set_halign (child, halign);
gtk_widget_set_valign (child, valign);
gtk_grid_attach (GTK_GRID (grid), child, column, row, width, height);
}
#endif
static GtkWidget *
chanlist_box_new (void)
{
#if HAVE_GTK3
GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous (GTK_BOX (box), FALSE);
return box;
#elif !HAVE_GTK3
return gtk_hbox_new (FALSE, 0);
#endif
}
static GtkWidget *
chanlist_icon_button (const char *label, const char *icon_name,
GCallback callback, gpointer userdata)
{
GtkWidget *button;
GtkWidget *image;
button = gtk_button_new_with_mnemonic (label);
#if HAVE_GTK3
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
#elif !HAVE_GTK3
image = gtk_image_new_from_stock (icon_name, GTK_ICON_SIZE_MENU);
#endif
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
g_signal_connect (G_OBJECT (button), "clicked", callback, userdata);
gtk_widget_show (button);
return button;
}
static GtkWidget *
chanlist_icon_menu_item (const char *label, const char *icon_name,
GCallback callback, gpointer userdata)
{
GtkWidget *item;
#if HAVE_GTK3
GtkWidget *box;
GtkWidget *image = NULL;
GtkWidget *label_widget;
const char *icon_name_gtk3;
item = gtk_menu_item_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
icon_name_gtk3 = gtkutil_icon_name_from_stock (icon_name);
if (!icon_name_gtk3)
icon_name_gtk3 = icon_name;
image = icon_name_gtk3 ? gtk_image_new_from_icon_name (icon_name_gtk3, GTK_ICON_SIZE_MENU) : NULL;
label_widget = gtk_label_new_with_mnemonic (label);
if (image)
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), label_widget, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (item), box);
#else
GtkWidget *image;
item = gtk_image_menu_item_new_with_mnemonic (label);
image = gtk_image_new_from_stock (icon_name, GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
#endif
g_signal_connect (G_OBJECT (item), "activate", callback, userdata);
gtk_widget_show_all (item);
return item;
}
static gboolean static gboolean
chanlist_match (server *serv, const char *str) chanlist_match (server *serv, const char *str)
@@ -621,18 +732,42 @@ chanlist_button_cb (GtkTreeView *tree, GdkEventButton *event, server *serv)
g_object_unref (menu); g_object_unref (menu);
g_signal_connect (G_OBJECT (menu), "selection-done", g_signal_connect (G_OBJECT (menu), "selection-done",
G_CALLBACK (chanlist_menu_destroy), NULL); G_CALLBACK (chanlist_menu_destroy), NULL);
mg_create_icon_item (_("_Join Channel"), GTK_STOCK_JUMP_TO, menu, {
chanlist_join, serv); GtkWidget *item;
mg_create_icon_item (_("_Copy Channel Name"), GTK_STOCK_COPY, menu,
chanlist_copychannel, serv); item = chanlist_icon_menu_item (_("_Join Channel"), ICON_CHANLIST_JOIN,
mg_create_icon_item (_("Copy _Topic Text"), GTK_STOCK_COPY, menu, G_CALLBACK (chanlist_join), serv);
chanlist_copytopic, serv); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = chanlist_icon_menu_item (_("_Copy Channel Name"), ICON_CHANLIST_COPY,
G_CALLBACK (chanlist_copychannel), serv);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = chanlist_icon_menu_item (_("Copy _Topic Text"), ICON_CHANLIST_COPY,
G_CALLBACK (chanlist_copytopic), serv);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
}
chan = chanlist_get_selected (serv, FALSE); chan = chanlist_get_selected (serv, FALSE);
menu_addfavoritemenu (serv, menu, chan, FALSE); menu_addfavoritemenu (serv, menu, chan, FALSE);
g_free (chan); g_free (chan);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, event->time); #if HAVE_GTK3
if (event)
{
gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *)event);
}
else
{
gtk_menu_popup_at_widget (GTK_MENU (menu), GTK_WIDGET (tree),
GDK_GRAVITY_SOUTH_WEST,
GDK_GRAVITY_NORTH_WEST,
NULL);
}
#endif
#if !HAVE_GTK3
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, event ? event->time : 0);
#endif
return TRUE; return TRUE;
} }
@@ -784,48 +919,108 @@ chanlist_opengui (server *serv, int do_refresh)
/* ============================================================= */ /* ============================================================= */
#if HAVE_GTK3
table = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (table), 12);
gtk_grid_set_row_spacing (GTK_GRID (table), 3);
#else
table = gtk_table_new (4, 4, FALSE); table = gtk_table_new (4, 4, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 12); gtk_table_set_col_spacings (GTK_TABLE (table), 12);
gtk_table_set_row_spacings (GTK_TABLE (table), 3); gtk_table_set_row_spacings (GTK_TABLE (table), 3);
#endif
gtk_box_pack_start (GTK_BOX (vbox), table, 0, 1, 0); gtk_box_pack_start (GTK_BOX (vbox), table, 0, 1, 0);
gtk_widget_show (table); gtk_widget_show (table);
wid = gtkutil_button (NULL, GTK_STOCK_FIND, 0, chanlist_search_pressed, serv, #if HAVE_GTK3
wid = chanlist_icon_button (_("_Search"), ICON_CHANLIST_FIND,
G_CALLBACK (chanlist_search_pressed), serv);
#endif
#if !HAVE_GTK3
wid = gtkutil_button (NULL, ICON_CHANLIST_FIND, 0, chanlist_search_pressed, serv,
_("_Search")); _("_Search"));
#endif
serv->gui->chanlist_search = wid; serv->gui->chanlist_search = wid;
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 3, 3, 1, 1, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_FILL);
#else
gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 3, 4, gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
wid = gtkutil_button (NULL, GTK_STOCK_REFRESH, 0, chanlist_refresh, serv, #if HAVE_GTK3
wid = chanlist_icon_button (_("_Download List"), ICON_CHANLIST_REFRESH,
G_CALLBACK (chanlist_refresh), serv);
#endif
#if !HAVE_GTK3
wid = gtkutil_button (NULL, ICON_CHANLIST_REFRESH, 0, chanlist_refresh, serv,
_("_Download List")); _("_Download List"));
#endif
serv->gui->chanlist_refresh = wid; serv->gui->chanlist_refresh = wid;
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 3, 2, 1, 1, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_FILL);
#else
gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 2, 3, gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
wid = gtkutil_button (NULL, GTK_STOCK_SAVE_AS, 0, chanlist_save, serv, #if HAVE_GTK3
wid = chanlist_icon_button (_("Save _List..."), ICON_CHANLIST_SAVE,
G_CALLBACK (chanlist_save), serv);
#endif
#if !HAVE_GTK3
wid = gtkutil_button (NULL, ICON_CHANLIST_SAVE, 0, chanlist_save, serv,
_("Save _List...")); _("Save _List..."));
#endif
serv->gui->chanlist_savelist = wid; serv->gui->chanlist_savelist = wid;
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 3, 1, 1, 1, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_FILL);
#else
gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 1, 2, gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
wid = gtkutil_button (NULL, GTK_STOCK_JUMP_TO, 0, chanlist_join, serv, #if HAVE_GTK3
wid = chanlist_icon_button (_("_Join Channel"), ICON_CHANLIST_JOIN,
G_CALLBACK (chanlist_join), serv);
#endif
#if !HAVE_GTK3
wid = gtkutil_button (NULL, ICON_CHANLIST_JOIN, 0, chanlist_join, serv,
_("_Join Channel")); _("_Join Channel"));
#endif
serv->gui->chanlist_join = wid; serv->gui->chanlist_join = wid;
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 3, 0, 1, 1, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_FILL);
#else
gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 0, 1, gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
/* ============================================================= */ /* ============================================================= */
wid = gtk_label_new (_("Show only:")); wid = gtk_label_new (_("Show only:"));
gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5); chanlist_set_label_alignment (wid);
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 0, 3, 1, 1, FALSE, FALSE,
GTK_ALIGN_START, GTK_ALIGN_CENTER);
#else
gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 3, 4, gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid); gtk_widget_show (wid);
hbox = gtk_hbox_new (0, 0); hbox = chanlist_box_new ();
gtk_box_set_spacing (GTK_BOX (hbox), 9); gtk_box_set_spacing (GTK_BOX (hbox), 9);
#if HAVE_GTK3
chanlist_grid_attach (table, hbox, 1, 3, 1, 1, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_FILL);
#else
gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 3, 4, gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 3, 4,
GTK_FILL, GTK_FILL, 0, 0); GTK_FILL, GTK_FILL, 0, 0);
#endif
gtk_widget_show (hbox); gtk_widget_show (hbox);
wid = gtk_label_new (_("channels with")); wid = gtk_label_new (_("channels with"));
@@ -860,15 +1055,25 @@ chanlist_opengui (server *serv, int do_refresh)
/* ============================================================= */ /* ============================================================= */
wid = gtk_label_new (_("Look in:")); wid = gtk_label_new (_("Look in:"));
gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5); chanlist_set_label_alignment (wid);
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 0, 2, 1, 1, FALSE, FALSE,
GTK_ALIGN_START, GTK_ALIGN_CENTER);
#else
gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 2, 3, gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid); gtk_widget_show (wid);
hbox = gtk_hbox_new (0, 0); hbox = chanlist_box_new ();
gtk_box_set_spacing (GTK_BOX (hbox), 12); gtk_box_set_spacing (GTK_BOX (hbox), 12);
#if HAVE_GTK3
chanlist_grid_attach (table, hbox, 1, 2, 1, 1, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_FILL);
#else
gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 2, 3, gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 2, 3,
GTK_FILL, GTK_FILL, 0, 0); GTK_FILL, GTK_FILL, 0, 0);
#endif
gtk_widget_show (hbox); gtk_widget_show (hbox);
wid = gtk_check_button_new_with_label (_("Channel name")); wid = gtk_check_button_new_with_label (_("Channel name"));
@@ -892,9 +1097,14 @@ chanlist_opengui (server *serv, int do_refresh)
/* ============================================================= */ /* ============================================================= */
wid = gtk_label_new (_("Search type:")); wid = gtk_label_new (_("Search type:"));
gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5); chanlist_set_label_alignment (wid);
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 0, 1, 1, 1, FALSE, FALSE,
GTK_ALIGN_START, GTK_ALIGN_CENTER);
#else
gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 1, 2, gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid); gtk_widget_show (wid);
wid = gtk_combo_box_text_new (); wid = gtk_combo_box_text_new ();
@@ -902,8 +1112,13 @@ chanlist_opengui (server *serv, int do_refresh)
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (wid), _("Pattern Match (Wildcards)")); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (wid), _("Pattern Match (Wildcards)"));
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (wid), _("Regular Expression")); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (wid), _("Regular Expression"));
gtk_combo_box_set_active (GTK_COMBO_BOX (wid), serv->gui->chanlist_search_type); gtk_combo_box_set_active (GTK_COMBO_BOX (wid), serv->gui->chanlist_search_type);
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 1, 1, 1, 1, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_CENTER);
#else
gtk_table_attach (GTK_TABLE (table), wid, 1, 2, 1, 2, gtk_table_attach (GTK_TABLE (table), wid, 1, 2, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
g_signal_connect (G_OBJECT (wid), "changed", g_signal_connect (G_OBJECT (wid), "changed",
G_CALLBACK (chanlist_combo_cb), serv); G_CALLBACK (chanlist_combo_cb), serv);
gtk_widget_show (wid); gtk_widget_show (wid);
@@ -911,9 +1126,14 @@ chanlist_opengui (server *serv, int do_refresh)
/* ============================================================= */ /* ============================================================= */
wid = gtk_label_new (_("Find:")); wid = gtk_label_new (_("Find:"));
gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5); chanlist_set_label_alignment (wid);
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 0, 0, 1, 1, FALSE, FALSE,
GTK_ALIGN_START, GTK_ALIGN_CENTER);
#else
gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 0, 1, gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid); gtk_widget_show (wid);
wid = gtk_entry_new (); wid = gtk_entry_new ();
@@ -923,8 +1143,13 @@ chanlist_opengui (server *serv, int do_refresh)
g_signal_connect (G_OBJECT (wid), "activate", g_signal_connect (G_OBJECT (wid), "activate",
G_CALLBACK (chanlist_search_pressed), G_CALLBACK (chanlist_search_pressed),
(gpointer) serv); (gpointer) serv);
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 1, 0, 1, 1, TRUE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_CENTER);
#else
gtk_table_attach (GTK_TABLE (table), wid, 1, 2, 0, 1, gtk_table_attach (GTK_TABLE (table), wid, 1, 2, 0, 1,
GTK_EXPAND | GTK_FILL, 0, 0, 0); GTK_EXPAND | GTK_FILL, 0, 0, 0);
#endif
gtk_widget_show (wid); gtk_widget_show (wid);
serv->gui->chanlist_wild = wid; serv->gui->chanlist_wild = wid;
@@ -932,9 +1157,18 @@ chanlist_opengui (server *serv, int do_refresh)
/* ============================================================= */ /* ============================================================= */
#if HAVE_GTK3
wid = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
#else
wid = gtk_vseparator_new (); wid = gtk_vseparator_new ();
#endif
#if HAVE_GTK3
chanlist_grid_attach (table, wid, 2, 0, 1, 5, FALSE, FALSE,
GTK_ALIGN_FILL, GTK_ALIGN_FILL);
#else
gtk_table_attach (GTK_TABLE (table), wid, 2, 3, 0, 5, gtk_table_attach (GTK_TABLE (table), wid, 2, 3, 0, 5,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid); gtk_widget_show (wid);
g_signal_connect (G_OBJECT (serv->gui->chanlist_window), "destroy", g_signal_connect (G_OBJECT (serv->gui->chanlist_window), "destroy",

View File

@@ -27,6 +27,13 @@ typedef struct
GtkWidget *b2; /* button2 */ GtkWidget *b2; /* button2 */
} tabview; } tabview;
#if HAVE_GTK3
#define ICON_CHANVIEW_CLOSE "window-close"
#endif
#if !HAVE_GTK3
#define ICON_CHANVIEW_CLOSE GTK_STOCK_CLOSE
#endif
static void chanview_populate (chanview *cv); static void chanview_populate (chanview *cv);
/* ignore "toggled" signal? */ /* ignore "toggled" signal? */
@@ -45,6 +52,26 @@ static int tab_right_is_moving = 0;
* *
*/ */
static inline gint
cv_tabs_get_viewport_size (GdkWindow *parent_win, gboolean vertical)
{
gint viewport_size = 0;
#if HAVE_GTK3
if (vertical)
viewport_size = gdk_window_get_height (parent_win);
else
viewport_size = gdk_window_get_width (parent_win);
#else
if (vertical)
gdk_window_get_geometry (parent_win, 0, 0, 0, &viewport_size, 0);
else
gdk_window_get_geometry (parent_win, 0, 0, &viewport_size, 0, 0);
#endif
return viewport_size;
}
/* /*
* GtkViewports request at least as much space as their children do. * GtkViewports request at least as much space as their children do.
* If we don't intervene here, the GtkViewport will be granted its * If we don't intervene here, the GtkViewport will be granted its
@@ -73,13 +100,13 @@ cv_tabs_sizealloc (GtkWidget *widget, GtkAllocation *allocation, chanview *cv)
if (cv->vertical) if (cv->vertical)
{ {
adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent (inner))); adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent (inner)));
gdk_window_get_geometry (parent_win, 0, 0, 0, &viewport_size, 0);
} else } else
{ {
adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent (inner))); adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent (inner)));
gdk_window_get_geometry (parent_win, 0, 0, &viewport_size, 0, 0);
} }
viewport_size = cv_tabs_get_viewport_size (parent_win, cv->vertical);
if (gtk_adjustment_get_upper (adj) <= viewport_size) if (gtk_adjustment_get_upper (adj) <= viewport_size)
{ {
gtk_widget_hide (((tabview *)cv)->b1); gtk_widget_hide (((tabview *)cv)->b1);
@@ -150,13 +177,13 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv)
if (cv->vertical) if (cv->vertical)
{ {
adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner)));
gdk_window_get_geometry (parent_win, 0, 0, 0, &viewport_size, 0);
} else } else
{ {
adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner)));
gdk_window_get_geometry (parent_win, 0, 0, &viewport_size, 0, 0);
} }
viewport_size = cv_tabs_get_viewport_size (parent_win, cv->vertical);
new_value = tab_search_offset (inner, gtk_adjustment_get_value (adj), 0, cv->vertical); new_value = tab_search_offset (inner, gtk_adjustment_get_value (adj), 0, cv->vertical);
if (new_value + viewport_size > gtk_adjustment_get_upper (adj)) if (new_value + viewport_size > gtk_adjustment_get_upper (adj))
@@ -199,13 +226,13 @@ tab_scroll_right_down_clicked (GtkWidget *widget, chanview *cv)
if (cv->vertical) if (cv->vertical)
{ {
adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); adj = gtk_viewport_get_vadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner)));
gdk_window_get_geometry (parent_win, 0, 0, 0, &viewport_size, 0);
} else } else
{ {
adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner))); adj = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gtk_widget_get_parent(inner)));
gdk_window_get_geometry (parent_win, 0, 0, &viewport_size, 0, 0);
} }
viewport_size = cv_tabs_get_viewport_size (parent_win, cv->vertical);
new_value = tab_search_offset (inner, gtk_adjustment_get_value (adj), 1, cv->vertical); new_value = tab_search_offset (inner, gtk_adjustment_get_value (adj), 1, cv->vertical);
if (new_value == 0 || new_value + viewport_size > gtk_adjustment_get_upper (adj)) if (new_value == 0 || new_value + viewport_size > gtk_adjustment_get_upper (adj))
@@ -266,9 +293,33 @@ static GtkWidget *
make_sbutton (GtkArrowType type, void *click_cb, void *userdata) make_sbutton (GtkArrowType type, void *click_cb, void *userdata)
{ {
GtkWidget *button, *arrow; GtkWidget *button, *arrow;
#if HAVE_GTK3
const char *icon_name = "pan-end-symbolic";
#endif
button = gtk_button_new (); button = gtk_button_new ();
#if HAVE_GTK3
switch (type)
{
case GTK_ARROW_UP:
icon_name = "pan-up-symbolic";
break;
case GTK_ARROW_DOWN:
icon_name = "pan-down-symbolic";
break;
case GTK_ARROW_LEFT:
icon_name = "pan-start-symbolic";
break;
case GTK_ARROW_RIGHT:
default:
icon_name = "pan-end-symbolic";
break;
}
arrow = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
#elif !HAVE_GTK3
arrow = gtk_arrow_new (type, GTK_SHADOW_NONE); arrow = gtk_arrow_new (type, GTK_SHADOW_NONE);
#endif
gtk_container_add (GTK_CONTAINER (button), arrow); gtk_container_add (GTK_CONTAINER (button), arrow);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
g_signal_connect (G_OBJECT (button), "clicked", g_signal_connect (G_OBJECT (button), "clicked",
@@ -289,9 +340,13 @@ cv_tabs_init (chanview *cv)
GtkWidget *button; GtkWidget *button;
if (cv->vertical) if (cv->vertical)
outer = gtk_vbox_new (0, 0); {
outer = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
}
else else
outer = gtk_hbox_new (0, 0); {
outer = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
}
((tabview *)cv)->outer = outer; ((tabview *)cv)->outer = outer;
g_signal_connect (G_OBJECT (outer), "size_allocate", g_signal_connect (G_OBJECT (outer), "size_allocate",
G_CALLBACK (cv_tabs_sizealloc), cv); G_CALLBACK (cv_tabs_sizealloc), cv);
@@ -308,9 +363,13 @@ cv_tabs_init (chanview *cv)
gtk_widget_show (viewport); gtk_widget_show (viewport);
if (cv->vertical) if (cv->vertical)
box = gtk_vbox_new (FALSE, 0); {
box = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
}
else else
box = gtk_hbox_new (FALSE, 0); {
box = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
}
((tabview *)cv)->inner = box; ((tabview *)cv)->inner = box;
gtk_container_add (GTK_CONTAINER (viewport), box); gtk_container_add (GTK_CONTAINER (viewport), box);
gtk_widget_show (box); gtk_widget_show (box);
@@ -318,7 +377,7 @@ cv_tabs_init (chanview *cv)
/* if vertical, the buttons can be side by side */ /* if vertical, the buttons can be side by side */
if (cv->vertical) if (cv->vertical)
{ {
hbox = gtk_hbox_new (FALSE, 0); hbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
gtk_box_pack_start (GTK_BOX (outer), hbox, 0, 0, 0); gtk_box_pack_start (GTK_BOX (outer), hbox, 0, 0, 0);
gtk_widget_show (hbox); gtk_widget_show (hbox);
} }
@@ -344,7 +403,7 @@ cv_tabs_init (chanview *cv)
gtk_box_pack_start (GTK_BOX (outer), ((tabview *)cv)->b1, 0, 0, 0); gtk_box_pack_start (GTK_BOX (outer), ((tabview *)cv)->b1, 0, 0, 0);
} }
button = gtkutil_button (outer, GTK_STOCK_CLOSE, NULL, cv_tabs_xclick_cb, button = gtkutil_button (outer, ICON_CHANVIEW_CLOSE, NULL, cv_tabs_xclick_cb,
cv, 0); cv, 0);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_widget_set_can_focus (button, FALSE); gtk_widget_set_can_focus (button, FALSE);
@@ -486,13 +545,21 @@ tab_add_real (chanview *cv, GtkWidget *tab, chan *ch)
if (cv->vertical) if (cv->vertical)
{ {
/* vertical */ /* vertical */
box = gtk_vbox_new (FALSE, 0); box = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
#if HAVE_GTK3
sep = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
#elif !HAVE_GTK3
sep = gtk_hseparator_new (); sep = gtk_hseparator_new ();
#endif
} else } else
{ {
/* horiz */ /* horiz */
box = gtk_hbox_new (FALSE, 0); box = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
#if HAVE_GTK3
sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
#elif !HAVE_GTK3
sep = gtk_vseparator_new (); sep = gtk_vseparator_new ();
#endif
} }
gtk_box_pack_end (GTK_BOX (box), sep, 0, 0, 4); gtk_box_pack_end (GTK_BOX (box), sep, 0, 0, 4);

View File

@@ -106,21 +106,37 @@ cv_tree_init (chanview *cv)
}; };
win = gtk_scrolled_window_new (0, 0); win = gtk_scrolled_window_new (0, 0);
gtk_widget_set_hexpand (win, TRUE);
gtk_widget_set_vexpand (win, TRUE);
/*gtk_container_set_border_width (GTK_CONTAINER (win), 1);*/ /*gtk_container_set_border_width (GTK_CONTAINER (win), 1);*/
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (win), gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (win),
GTK_SHADOW_IN); GTK_SHADOW_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (win), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (win),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (cv->box), win); gtk_container_add (GTK_CONTAINER (cv->box), win);
gtk_widget_show (win); gtk_widget_show (win);
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (cv->store)); view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (cv->store));
gtk_widget_set_hexpand (view, TRUE);
gtk_widget_set_vexpand (view, TRUE);
gtk_widget_set_name (view, "zoitechat-tree"); gtk_widget_set_name (view, "zoitechat-tree");
if (cv->style) if (
#if HAVE_GTK3
cv->font_desc
#else
cv->style
#endif
)
{ {
gtk_widget_modify_base (view, GTK_STATE_NORMAL, &cv->style->base[GTK_STATE_NORMAL]); #if HAVE_GTK3
gtk_widget_modify_text (view, GTK_STATE_NORMAL, &cv->style->text[GTK_STATE_NORMAL]); gtkutil_apply_palette (view, &colors[COL_BG], &colors[COL_FG],
gtk_widget_modify_font (view, cv->style->font_desc); cv->font_desc);
#else
gtkutil_apply_palette (view, &cv->style->base[GTK_STATE_NORMAL],
&cv->style->text[GTK_STATE_NORMAL],
cv->style->font_desc);
#endif
} }
/*gtk_widget_modify_base (view, GTK_STATE_NORMAL, &colors[COL_BG]);*/ /*gtk_widget_modify_base (view, GTK_STATE_NORMAL, &colors[COL_BG]);*/
gtk_widget_set_can_focus (view, FALSE); gtk_widget_set_can_focus (view, FALSE);
@@ -160,6 +176,7 @@ cv_tree_init (chanview *cv)
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1); gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_set_attributes (col, renderer, "text", COL_NAME, "attributes", COL_ATTR, NULL); gtk_tree_view_column_set_attributes (col, renderer, "text", COL_NAME, "attributes", COL_ATTR, NULL);
gtk_tree_view_column_set_expand (col, TRUE);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (view))), g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (view))),

View File

@@ -45,7 +45,11 @@ struct _chanview
int size; /* number of channels in view */ int size; /* number of channels in view */
GtkWidget *box; /* the box we destroy when changing implementations */ GtkWidget *box; /* the box we destroy when changing implementations */
GtkStyle *style; /* style used for tree */ #if HAVE_GTK3
PangoFontDescription *font_desc; /* font used for tree */
#else
InputStyle *style; /* style used for tree */
#endif
chan *focused; /* currently focused channel */ chan *focused; /* currently focused channel */
int trunc_len; int trunc_len;
@@ -109,6 +113,7 @@ chanview_apply_theme (chanview *cv)
{ {
GtkWidget *w; GtkWidget *w;
treeview *tv; treeview *tv;
const PangoFontDescription *font = NULL;
if (cv == NULL) if (cv == NULL)
return; return;
@@ -122,16 +127,17 @@ chanview_apply_theme (chanview *cv)
return; return;
w = GTK_WIDGET (tv->tree); w = GTK_WIDGET (tv->tree);
if (input_style)
font = input_style->font_desc;
if (fe_dark_mode_is_enabled () || prefs.hex_gui_dark_mode == ZOITECHAT_DARK_MODE_LIGHT) if (fe_dark_mode_is_enabled () || prefs.hex_gui_dark_mode == ZOITECHAT_DARK_MODE_LIGHT)
{ {
gtk_widget_modify_base (w, GTK_STATE_NORMAL, &colors[COL_BG]); gtkutil_apply_palette (w, &colors[COL_BG], &colors[COL_FG], font);
gtk_widget_modify_text (w, GTK_STATE_NORMAL, &colors[COL_FG]);
} }
else else
{ {
/* Revert back to theme defaults. */ /* Keep list font in sync while reverting colors to theme defaults. */
gtk_widget_modify_base (w, GTK_STATE_NORMAL, NULL); gtkutil_apply_palette (w, NULL, NULL, font);
gtk_widget_modify_text (w, GTK_STATE_NORMAL, NULL);
} }
} }
@@ -294,15 +300,28 @@ chanview_box_destroy_cb (GtkWidget *box, chanview *cv)
chanview * chanview *
chanview_new (int type, int trunc_len, gboolean sort, gboolean use_icons, chanview_new (int type, int trunc_len, gboolean sort, gboolean use_icons,
GtkStyle *style) #if HAVE_GTK3
PangoFontDescription *font_desc
#else
InputStyle *style
#endif
)
{ {
chanview *cv; chanview *cv;
cv = g_new0 (chanview, 1); cv = g_new0 (chanview, 1);
cv->store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_POINTER, cv->store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_POINTER,
PANGO_TYPE_ATTR_LIST, GDK_TYPE_PIXBUF); PANGO_TYPE_ATTR_LIST, GDK_TYPE_PIXBUF);
#if HAVE_GTK3
cv->font_desc = font_desc;
#else
cv->style = style; cv->style = style;
#endif
#if HAVE_GTK3
cv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
#elif !HAVE_GTK3
cv->box = gtk_hbox_new (0, 0); cv->box = gtk_hbox_new (0, 0);
#endif
cv->trunc_len = trunc_len; cv->trunc_len = trunc_len;
cv->sorted = sort; cv->sorted = sort;
cv->use_icons = use_icons; cv->use_icons = use_icons;

View File

@@ -20,10 +20,18 @@
#ifndef ZOITECHAT_CHANVIEW_H #ifndef ZOITECHAT_CHANVIEW_H
#define ZOITECHAT_CHANVIEW_H #define ZOITECHAT_CHANVIEW_H
#include "fe-gtk.h"
typedef struct _chanview chanview; typedef struct _chanview chanview;
typedef struct _chan chan; typedef struct _chan chan;
chanview *chanview_new (int type, int trunc_len, gboolean sort, gboolean use_icons, GtkStyle *style); chanview *chanview_new (int type, int trunc_len, gboolean sort, gboolean use_icons,
#if HAVE_GTK3
PangoFontDescription *font_desc
#else
InputStyle *style
#endif
);
void chanview_set_callbacks (chanview *cv, void chanview_set_callbacks (chanview *cv,
void (*cb_focus) (chanview *, chan *, int tag, void *userdata), void (*cb_focus) (chanview *, chan *, int tag, void *userdata),
void (*cb_xbutton) (chanview *, chan *, int tag, void *userdata), void (*cb_xbutton) (chanview *, chan *, int tag, void *userdata),

View File

@@ -101,9 +101,13 @@ static void custom_list_sortable_set_default_sort_func (GtkTreeSortable *
static gboolean custom_list_sortable_has_default_sort_func (GtkTreeSortable * static gboolean custom_list_sortable_has_default_sort_func (GtkTreeSortable *
sortable); sortable);
static void custom_list_sortable_init (GtkTreeSortableIface * iface);
static GObjectClass *parent_class = NULL; /* GObject stuff - nothing to worry about */
G_DEFINE_TYPE_WITH_CODE (CustomList, custom_list, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, custom_list_tree_model_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE, custom_list_sortable_init))
static void static void
@@ -116,70 +120,6 @@ custom_list_sortable_init (GtkTreeSortableIface * iface)
iface->has_default_sort_func = custom_list_sortable_has_default_sort_func; /* NOT SUPPORTED */ iface->has_default_sort_func = custom_list_sortable_has_default_sort_func; /* NOT SUPPORTED */
} }
/*****************************************************************************
*
* custom_list_get_type: here we register our new type and its interfaces
* with the type system. If you want to implement
* additional interfaces like GtkTreeSortable, you
* will need to do it here.
*
*****************************************************************************/
GType
custom_list_get_type (void)
{
static GType custom_list_type = 0;
if (custom_list_type)
return custom_list_type;
/* Some boilerplate type registration stuff */
{
static const GTypeInfo custom_list_info = {
sizeof (CustomListClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) custom_list_class_init,
NULL, /* class finalize */
NULL, /* class_data */
sizeof (CustomList),
0, /* n_preallocs */
(GInstanceInitFunc) custom_list_init
};
custom_list_type =
g_type_register_static (G_TYPE_OBJECT, "CustomList",
&custom_list_info, (GTypeFlags) 0);
}
/* Here we register our GtkTreeModel interface with the type system */
{
static const GInterfaceInfo tree_model_info = {
(GInterfaceInitFunc) custom_list_tree_model_init,
NULL,
NULL
};
g_type_add_interface_static (custom_list_type, GTK_TYPE_TREE_MODEL,
&tree_model_info);
}
/* Add GtkTreeSortable interface */
{
static const GInterfaceInfo tree_sortable_info = {
(GInterfaceInitFunc) custom_list_sortable_init,
NULL,
NULL
};
g_type_add_interface_static (custom_list_type,
GTK_TYPE_TREE_SORTABLE,
&tree_sortable_info);
}
return custom_list_type;
}
/***************************************************************************** /*****************************************************************************
* *
* custom_list_class_init: more boilerplate GObject/GType stuff. * custom_list_class_init: more boilerplate GObject/GType stuff.
@@ -193,7 +133,6 @@ custom_list_class_init (CustomListClass * klass)
{ {
GObjectClass *object_class; GObjectClass *object_class;
parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
object_class = (GObjectClass *) klass; object_class = (GObjectClass *) klass;
object_class->finalize = custom_list_finalize; object_class->finalize = custom_list_finalize;
@@ -265,7 +204,7 @@ custom_list_finalize (GObject * object)
custom_list_clear (CUSTOM_LIST (object)); custom_list_clear (CUSTOM_LIST (object));
/* must chain up - finalize parent */ /* must chain up - finalize parent */
(*parent_class->finalize) (object); G_OBJECT_CLASS (custom_list_parent_class)->finalize (object);
} }

View File

@@ -22,6 +22,9 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
typedef struct _CustomList CustomList;
typedef struct _CustomListClass CustomListClass;
GType custom_list_get_type (void); GType custom_list_get_type (void);
/* Some boilerplate GObject defines. 'klass' is used /* Some boilerplate GObject defines. 'klass' is used
@@ -62,20 +65,19 @@ typedef struct
} }
chanlistrow; chanlistrow;
typedef struct _CustomList CustomList;
typedef struct _CustomListClass CustomListClass;
/* CustomList: this structure contains everything we need for our /* CustomList: this structure contains everything we need for our
* model implementation. You can add extra fields to * model implementation. You can add extra fields to
* this structure, e.g. hashtables to quickly lookup * this structure, e.g. hashtables to quickly lookup
* rows or whatever else you might need, but it is * rows or whatever else you might need, but it is
* crucial that 'parent' is the first member of the * crucial that 'parent_instance' is the first member of the
* structure. */ * structure. */
struct _CustomList struct _CustomList
{ {
#if HAVE_GTK3
GObject parent_instance;
#else
GObject parent; GObject parent;
#endif
guint num_rows; /* number of rows that we have used */ guint num_rows; /* number of rows that we have used */
guint num_alloc; /* number of rows allocated */ guint num_alloc; /* number of rows allocated */

View File

@@ -37,6 +37,19 @@
#include "palette.h" #include "palette.h"
#include "maingui.h" #include "maingui.h"
#if HAVE_GTK3
#define ICON_DCC_CANCEL "dialog-cancel"
#define ICON_DCC_ACCEPT "dialog-apply"
#define ICON_DCC_RESUME "view-refresh"
#define ICON_DCC_CLEAR "edit-clear"
#endif
#if !HAVE_GTK3
#define ICON_DCC_CANCEL GTK_STOCK_CANCEL
#define ICON_DCC_ACCEPT GTK_STOCK_APPLY
#define ICON_DCC_RESUME GTK_STOCK_REFRESH
#define ICON_DCC_CLEAR GTK_STOCK_CLEAR
#endif
enum /* DCC SEND/RECV */ enum /* DCC SEND/RECV */
{ {
@@ -50,7 +63,7 @@ enum /* DCC SEND/RECV */
COL_ETA, COL_ETA,
COL_NICK, COL_NICK,
COL_DCC, /* struct DCC * */ COL_DCC, /* struct DCC * */
COL_COLOR, /* GdkColor */ COL_COLOR, /* PaletteColor */
N_COLUMNS N_COLUMNS
}; };
@@ -62,7 +75,7 @@ enum /* DCC CHAT */
CCOL_SENT, CCOL_SENT,
CCOL_START, CCOL_START,
CCOL_DCC, /* struct DCC * */ CCOL_DCC, /* struct DCC * */
CCOL_COLOR, /* GdkColor * */ CCOL_COLOR, /* PaletteColor * */
CN_COLUMNS CN_COLUMNS
}; };
@@ -103,6 +116,26 @@ static short view_mode; /* 1=download 2=upload 3=both */
#define VIEW_UPLOAD 2 #define VIEW_UPLOAD 2
#define VIEW_BOTH 3 #define VIEW_BOTH 3
#if HAVE_GTK3
static GdkPixbuf *
dcc_load_icon (const char *stock_name)
{
GtkIconTheme *theme = gtk_icon_theme_get_default ();
const char *icon_name = gtkutil_icon_name_from_stock (stock_name);
int width = 16;
int height = 16;
if (g_strcmp0 (stock_name, "gtk-go-up") == 0)
icon_name = "go-up";
else if (g_strcmp0 (stock_name, "gtk-go-down") == 0)
icon_name = "go-down";
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
return gtk_icon_theme_load_icon (theme, icon_name, width, 0, NULL);
}
#endif
static void static void
proper_unit (guint64 size, char *buf, size_t buf_len) proper_unit (guint64 size, char *buf, size_t buf_len)
@@ -151,6 +184,29 @@ fe_dcc_send_filereq (struct session *sess, char *nick, int maxcps, int passive)
g_free (tbuf); g_free (tbuf);
} }
static void
dcc_store_color (GtkListStore *store, GtkTreeIter *iter, int column, int color_index)
{
const PaletteColor *color = NULL;
if (color_index != 1)
color = &colors[color_index];
#if HAVE_GTK3
if (color)
{
GdkRGBA rgba = *color;
gtk_list_store_set (store, iter, column, &rgba, -1);
}
else
{
gtk_list_store_set (store, iter, column, NULL, -1);
}
#else
gtk_list_store_set (store, iter, column, color, -1);
#endif
}
static void static void
dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter, dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
gboolean update_only) gboolean update_only)
@@ -171,11 +227,8 @@ dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
CCOL_SENT, size, CCOL_SENT, size,
CCOL_START, date, CCOL_START, date,
CCOL_DCC, dcc, CCOL_DCC, dcc,
CCOL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1); -1);
dcc_store_color (store, iter, CCOL_COLOR, dccstat[dcc->dccstat].color);
} }
static void static void
@@ -187,8 +240,12 @@ dcc_prepare_row_send (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
float per; float per;
if (!pix_up) if (!pix_up)
#if HAVE_GTK3
pix_up = dcc_load_icon ("gtk-go-up");
#elif !HAVE_GTK3
pix_up = gtk_widget_render_icon (dccfwin.window, "gtk-go-up", pix_up = gtk_widget_render_icon (dccfwin.window, "gtk-go-up",
GTK_ICON_SIZE_MENU, NULL); GTK_ICON_SIZE_MENU, NULL);
#endif
/* percentage ack'ed */ /* percentage ack'ed */
per = (float) ((dcc->ack * 100.00) / dcc->size); per = (float) ((dcc->ack * 100.00) / dcc->size);
@@ -211,10 +268,6 @@ dcc_prepare_row_send (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
COL_PERC, perc, COL_PERC, perc,
COL_SPEED, kbs, COL_SPEED, kbs,
COL_ETA, eta, COL_ETA, eta,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1); -1);
else else
gtk_list_store_set (store, iter, gtk_list_store_set (store, iter,
@@ -228,11 +281,8 @@ dcc_prepare_row_send (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
COL_ETA, eta, COL_ETA, eta,
COL_NICK, dcc->nick, COL_NICK, dcc->nick,
COL_DCC, dcc, COL_DCC, dcc,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1); -1);
dcc_store_color (store, iter, COL_COLOR, dccstat[dcc->dccstat].color);
} }
static void static void
@@ -244,8 +294,12 @@ dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
int to_go; int to_go;
if (!pix_dn) if (!pix_dn)
#if HAVE_GTK3
pix_dn = dcc_load_icon ("gtk-go-down");
#elif !HAVE_GTK3
pix_dn = gtk_widget_render_icon (dccfwin.window, "gtk-go-down", pix_dn = gtk_widget_render_icon (dccfwin.window, "gtk-go-down",
GTK_ICON_SIZE_MENU, NULL); GTK_ICON_SIZE_MENU, NULL);
#endif
proper_unit (dcc->size, size, sizeof (size)); proper_unit (dcc->size, size, sizeof (size));
if (dcc->dccstat == STAT_QUEUED) if (dcc->dccstat == STAT_QUEUED)
@@ -271,10 +325,6 @@ dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
COL_PERC, perc, COL_PERC, perc,
COL_SPEED, kbs, COL_SPEED, kbs,
COL_ETA, eta, COL_ETA, eta,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1); -1);
else else
gtk_list_store_set (store, iter, gtk_list_store_set (store, iter,
@@ -288,11 +338,8 @@ dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
COL_ETA, eta, COL_ETA, eta,
COL_NICK, dcc->nick, COL_NICK, dcc->nick,
COL_DCC, dcc, COL_DCC, dcc,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1); -1);
dcc_store_color (store, iter, COL_COLOR, dccstat[dcc->dccstat].color);
} }
static gboolean static gboolean
@@ -730,7 +777,7 @@ dcc_add_column (GtkWidget *tree, int textcol, int colorcol, char *title, gboolea
if (right_justified) if (right_justified)
g_object_set (G_OBJECT (renderer), "xalign", (float) 1.0, NULL); g_object_set (G_OBJECT (renderer), "xalign", (float) 1.0, NULL);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, title, renderer, gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, title, renderer,
"text", textcol, "foreground-gdk", colorcol, "text", textcol, PALETTE_FOREGROUND_PROPERTY, colorcol,
NULL); NULL);
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1); gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
} }
@@ -744,13 +791,31 @@ dcc_detail_label (char *text, GtkWidget *box, int num)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
g_snprintf (buf, sizeof (buf), "<b>%s</b>", text); g_snprintf (buf, sizeof (buf), "<b>%s</b>", text);
gtk_label_set_markup (GTK_LABEL (label), buf); gtk_label_set_markup (GTK_LABEL (label), buf);
#if HAVE_GTK3
gtk_widget_set_hexpand (label, FALSE);
gtk_widget_set_vexpand (label, FALSE);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_START);
gtk_grid_attach (GTK_GRID (box), label, 0, 0 + num, 1, 1);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
gtk_table_attach (GTK_TABLE (box), label, 0, 1, 0 + num, 1 + num, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (box), label, 0, 1, 0 + num, 1 + num,
GTK_FILL, GTK_FILL, 0, 0);
#endif
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_selectable (GTK_LABEL (label), TRUE); gtk_label_set_selectable (GTK_LABEL (label), TRUE);
#if HAVE_GTK3
gtk_widget_set_hexpand (label, FALSE);
gtk_widget_set_vexpand (label, FALSE);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_START);
gtk_grid_attach (GTK_GRID (box), label, 1, 0 + num, 1, 1);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
gtk_table_attach (GTK_TABLE (box), label, 1, 2, 0 + num, 1 + num, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (box), label, 1, 2, 0 + num, 1 + num,
GTK_FILL, GTK_FILL, 0, 0);
#endif
return label; return label;
} }
@@ -789,7 +854,7 @@ dcc_configure_cb (GtkWindow *win, GdkEventConfigure *event, gpointer data)
int int
fe_dcc_open_recv_win (int passive) fe_dcc_open_recv_win (int passive)
{ {
GtkWidget *radio, *table, *vbox, *bbox, *view, *exp, *detailbox; GtkWidget *radio, *table, *vbox, *bbox, *view, *view_scrolled, *exp, *detailbox;
GtkListStore *store; GtkListStore *store;
GSList *group; GSList *group;
char buf[128]; char buf[128];
@@ -810,8 +875,13 @@ fe_dcc_open_recv_win (int passive)
store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_COLOR); G_TYPE_STRING, G_TYPE_POINTER, PALETTE_GDK_TYPE);
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1); view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
view_scrolled = gtk_widget_get_parent (view);
gtk_widget_set_hexpand (view_scrolled, TRUE);
gtk_widget_set_vexpand (view_scrolled, TRUE);
gtk_widget_set_hexpand (view, TRUE);
gtk_widget_set_vexpand (view, TRUE);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
/* Up/Down Icon column */ /* Up/Down Icon column */
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, NULL, gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, NULL,
@@ -844,49 +914,106 @@ fe_dcc_open_recv_win (int passive)
g_signal_connect (G_OBJECT (view), "row-activated", g_signal_connect (G_OBJECT (view), "row-activated",
G_CALLBACK (dcc_dclick_cb), NULL); G_CALLBACK (dcc_dclick_cb), NULL);
#if HAVE_GTK3
table = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (table), 16);
#else
table = gtk_table_new (1, 3, FALSE); table = gtk_table_new (1, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 16); gtk_table_set_col_spacings (GTK_TABLE (table), 16);
#endif
gtk_box_pack_start (GTK_BOX (vbox), table, 0, 0, 0); gtk_box_pack_start (GTK_BOX (vbox), table, 0, 0, 0);
radio = gtk_radio_button_new_with_mnemonic (NULL, _("Both")); radio = gtk_radio_button_new_with_mnemonic (NULL, _("Both"));
g_signal_connect (G_OBJECT (radio), "toggled", g_signal_connect (G_OBJECT (radio), "toggled",
G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_BOTH)); G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_BOTH));
#if HAVE_GTK3
gtk_widget_set_hexpand (radio, FALSE);
gtk_widget_set_vexpand (radio, FALSE);
gtk_widget_set_halign (radio, GTK_ALIGN_FILL);
gtk_widget_set_valign (radio, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), radio, 3, 0, 1, 1);
#else
gtk_table_attach (GTK_TABLE (table), radio, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (table), radio, 3, 4, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
#endif
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
radio = gtk_radio_button_new_with_mnemonic (group, _("Uploads")); radio = gtk_radio_button_new_with_mnemonic (group, _("Uploads"));
g_signal_connect (G_OBJECT (radio), "toggled", g_signal_connect (G_OBJECT (radio), "toggled",
G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_UPLOAD)); G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_UPLOAD));
#if HAVE_GTK3
gtk_widget_set_hexpand (radio, FALSE);
gtk_widget_set_vexpand (radio, FALSE);
gtk_widget_set_halign (radio, GTK_ALIGN_FILL);
gtk_widget_set_valign (radio, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), radio, 1, 0, 1, 1);
#else
gtk_table_attach (GTK_TABLE (table), radio, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (table), radio, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
#endif
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
radio = gtk_radio_button_new_with_mnemonic (group, _("Downloads")); radio = gtk_radio_button_new_with_mnemonic (group, _("Downloads"));
g_signal_connect (G_OBJECT (radio), "toggled", g_signal_connect (G_OBJECT (radio), "toggled",
G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_DOWNLOAD)); G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_DOWNLOAD));
#if HAVE_GTK3
gtk_widget_set_hexpand (radio, FALSE);
gtk_widget_set_vexpand (radio, FALSE);
gtk_widget_set_halign (radio, GTK_ALIGN_FILL);
gtk_widget_set_valign (radio, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), radio, 2, 0, 1, 1);
#else
gtk_table_attach (GTK_TABLE (table), radio, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (table), radio, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
#endif
exp = gtk_expander_new (_("Details")); exp = gtk_expander_new (_("Details"));
#if HAVE_GTK3
gtk_widget_set_hexpand (exp, TRUE);
gtk_widget_set_vexpand (exp, FALSE);
gtk_widget_set_halign (exp, GTK_ALIGN_FILL);
gtk_widget_set_valign (exp, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), exp, 0, 0, 1, 1);
#else
gtk_table_attach (GTK_TABLE (table), exp, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (table), exp, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
#if HAVE_GTK3
detailbox = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (detailbox), 6);
gtk_grid_set_row_spacing (GTK_GRID (detailbox), 2);
gtk_container_set_border_width (GTK_CONTAINER (detailbox), 6);
#else
detailbox = gtk_table_new (3, 3, FALSE); detailbox = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (detailbox), 6); gtk_table_set_col_spacings (GTK_TABLE (detailbox), 6);
gtk_table_set_row_spacings (GTK_TABLE (detailbox), 2); gtk_table_set_row_spacings (GTK_TABLE (detailbox), 2);
gtk_container_set_border_width (GTK_CONTAINER (detailbox), 6); gtk_container_set_border_width (GTK_CONTAINER (detailbox), 6);
#endif
g_signal_connect (G_OBJECT (exp), "activate", g_signal_connect (G_OBJECT (exp), "activate",
G_CALLBACK (dcc_exp_cb), detailbox); G_CALLBACK (dcc_exp_cb), detailbox);
#if HAVE_GTK3
gtk_widget_set_hexpand (detailbox, TRUE);
gtk_widget_set_vexpand (detailbox, FALSE);
gtk_widget_set_halign (detailbox, GTK_ALIGN_FILL);
gtk_widget_set_valign (detailbox, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), detailbox, 0, 1, 4, 1);
#else
gtk_table_attach (GTK_TABLE (table), detailbox, 0, 4, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach (GTK_TABLE (table), detailbox, 0, 4, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
#endif
dccfwin.file_label = dcc_detail_label (_("File:"), detailbox, 0); dccfwin.file_label = dcc_detail_label (_("File:"), detailbox, 0);
dccfwin.address_label = dcc_detail_label (_("Address:"), detailbox, 1); dccfwin.address_label = dcc_detail_label (_("Address:"), detailbox, 1);
#if HAVE_GTK3
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
bbox = gtk_hbutton_box_new (); bbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, FALSE, 2); gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, FALSE, 2);
dccfwin.abort_button = gtkutil_button (bbox, GTK_STOCK_CANCEL, 0, abort_clicked, 0, _("Abort")); dccfwin.abort_button = gtkutil_button (bbox, ICON_DCC_CANCEL, 0, abort_clicked, 0, _("Abort"));
dccfwin.accept_button = gtkutil_button (bbox, GTK_STOCK_APPLY, 0, accept_clicked, 0, _("Accept")); dccfwin.accept_button = gtkutil_button (bbox, ICON_DCC_ACCEPT, 0, accept_clicked, 0, _("Accept"));
dccfwin.resume_button = gtkutil_button (bbox, GTK_STOCK_REFRESH, 0, resume_clicked, 0, _("Resume")); dccfwin.resume_button = gtkutil_button (bbox, ICON_DCC_RESUME, 0, resume_clicked, 0, _("Resume"));
dccfwin.clear_button = gtkutil_button (bbox, GTK_STOCK_CLEAR, 0, clear_completed, 0, _("Clear")); dccfwin.clear_button = gtkutil_button (bbox, ICON_DCC_CLEAR, 0, clear_completed, 0, _("Clear"));
dccfwin.open_button = gtkutil_button (bbox, 0, 0, browse_dcc_folder, 0, _("Open Folder...")); dccfwin.open_button = gtkutil_button (bbox, 0, 0, browse_dcc_folder, 0, _("Open Folder..."));
gtk_widget_set_sensitive (dccfwin.accept_button, FALSE); gtk_widget_set_sensitive (dccfwin.accept_button, FALSE);
gtk_widget_set_sensitive (dccfwin.resume_button, FALSE); gtk_widget_set_sensitive (dccfwin.resume_button, FALSE);
@@ -1036,7 +1163,7 @@ dcc_chat_dclick_cb (GtkTreeView *view, GtkTreePath *path,
int int
fe_dcc_open_chat_win (int passive) fe_dcc_open_chat_win (int passive)
{ {
GtkWidget *view, *vbox, *bbox; GtkWidget *view, *vbox, *bbox, *scroll;
GtkListStore *store; GtkListStore *store;
char buf[128]; char buf[128];
@@ -1056,9 +1183,11 @@ fe_dcc_open_chat_win (int passive)
gtk_box_set_spacing (GTK_BOX (vbox), 3); gtk_box_set_spacing (GTK_BOX (vbox), 3);
store = gtk_list_store_new (CN_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, store = gtk_list_store_new (CN_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_POINTER, GDK_TYPE_COLOR); G_TYPE_POINTER, PALETTE_GDK_TYPE);
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1); view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
scroll = gtk_widget_get_parent (view);
gtk_box_set_child_packing (GTK_BOX (vbox), scroll, TRUE, TRUE, 0, GTK_PACK_START);
dcc_add_column (view, CCOL_STATUS, CCOL_COLOR, _("Status"), FALSE); dcc_add_column (view, CCOL_STATUS, CCOL_COLOR, _("Status"), FALSE);
dcc_add_column (view, CCOL_NICK, CCOL_COLOR, _("Nick"), FALSE); dcc_add_column (view, CCOL_NICK, CCOL_COLOR, _("Nick"), FALSE);
@@ -1080,12 +1209,17 @@ fe_dcc_open_chat_win (int passive)
g_signal_connect (G_OBJECT (view), "row-activated", g_signal_connect (G_OBJECT (view), "row-activated",
G_CALLBACK (dcc_chat_dclick_cb), NULL); G_CALLBACK (dcc_chat_dclick_cb), NULL);
#if HAVE_GTK3
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
bbox = gtk_hbutton_box_new (); bbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, FALSE, 2); gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, FALSE, 2);
dcccwin.abort_button = gtkutil_button (bbox, GTK_STOCK_CANCEL, 0, abort_chat_clicked, 0, _("Abort")); dcccwin.abort_button = gtkutil_button (bbox, ICON_DCC_CANCEL, 0, abort_chat_clicked, 0, _("Abort"));
dcccwin.accept_button = gtkutil_button (bbox, GTK_STOCK_APPLY, 0, accept_chat_clicked, 0, _("Accept")); dcccwin.accept_button = gtkutil_button (bbox, ICON_DCC_ACCEPT, 0, accept_chat_clicked, 0, _("Accept"));
gtk_widget_set_sensitive (dcccwin.accept_button, FALSE); gtk_widget_set_sensitive (dcccwin.accept_button, FALSE);
gtk_widget_set_sensitive (dcccwin.abort_button, FALSE); gtk_widget_set_sensitive (dcccwin.abort_button, FALSE);

View File

@@ -42,6 +42,19 @@
#include "maingui.h" #include "maingui.h"
#include "editlist.h" #include "editlist.h"
#if HAVE_GTK3
#define ICON_EDITLIST_NEW "document-new"
#define ICON_EDITLIST_DELETE "edit-delete"
#define ICON_EDITLIST_CANCEL "dialog-cancel"
#define ICON_EDITLIST_SAVE "document-save"
#endif
#if !HAVE_GTK3
#define ICON_EDITLIST_NEW GTK_STOCK_NEW
#define ICON_EDITLIST_DELETE GTK_STOCK_DELETE
#define ICON_EDITLIST_CANCEL GTK_STOCK_CANCEL
#define ICON_EDITLIST_SAVE GTK_STOCK_SAVE
#endif
enum enum
{ {
NAME_COLUMN, NAME_COLUMN,
@@ -316,7 +329,7 @@ editlist_treeview_new (GtkWidget *box, char *title1, char *title2)
gtk_tree_view_column_set_min_width (col, 100); gtk_tree_view_column_set_min_width (col, 100);
gtk_container_add (GTK_CONTAINER (scroll), view); gtk_container_add (GTK_CONTAINER (scroll), view);
gtk_container_add (GTK_CONTAINER (box), scroll); gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
gtk_widget_show_all (box); gtk_widget_show_all (box);
return view; return view;
@@ -348,19 +361,24 @@ editlist_gui_open (char *title1, char *title2, GSList *list, char *title, char *
if (help) if (help)
gtk_widget_set_tooltip_text (view, help); gtk_widget_set_tooltip_text (view, help);
#if HAVE_GTK3
box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
box = gtk_hbutton_box_new (); box = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
#endif
gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (box), 5); gtk_container_set_border_width (GTK_CONTAINER (box), 5);
gtk_widget_show (box); gtk_widget_show (box);
gtkutil_button (box, GTK_STOCK_NEW, 0, editlist_add, gtkutil_button (box, ICON_EDITLIST_NEW, 0, editlist_add,
NULL, _("Add")); NULL, _("Add"));
gtkutil_button (box, GTK_STOCK_DELETE, 0, editlist_delete, gtkutil_button (box, ICON_EDITLIST_DELETE, 0, editlist_delete,
NULL, _("Delete")); NULL, _("Delete"));
gtkutil_button (box, GTK_STOCK_CANCEL, 0, editlist_close, gtkutil_button (box, ICON_EDITLIST_CANCEL, 0, editlist_close,
NULL, _("Cancel")); NULL, _("Cancel"));
gtkutil_button (box, GTK_STOCK_SAVE, 0, editlist_save, gtkutil_button (box, ICON_EDITLIST_SAVE, 0, editlist_save,
file, _("Save")); file, _("Save"));
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view))); store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));

View File

@@ -22,8 +22,11 @@
#include "fe-gtk.h" #include "fe-gtk.h"
#ifdef WIN32 #ifdef GDK_WINDOWING_WIN32
#include <gdk/gdkwin32.h> #include <gdk/gdkwin32.h>
#endif
#ifdef WIN32
#include <windows.h> #include <windows.h>
#else #else
#include <unistd.h> #include <unistd.h>
@@ -112,6 +115,27 @@ create_msg_dialog (gchar *title, gchar *message)
gtk_dialog_run (GTK_DIALOG (dialog)); gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
} }
static void
win32_set_gsettings_schema_dir (void)
{
char *base_path;
char *schema_path;
if (g_getenv ("GSETTINGS_SCHEMA_DIR") != NULL)
return;
base_path = g_win32_get_package_installation_directory_of_module (NULL);
if (base_path == NULL)
return;
schema_path = g_build_filename (base_path, "share", "glib-2.0", "schemas", NULL);
if (g_file_test (schema_path, G_FILE_TEST_IS_DIR))
g_setenv ("GSETTINGS_SCHEMA_DIR", schema_path, FALSE);
g_free (schema_path);
g_free (base_path);
}
#endif #endif
int int
@@ -120,6 +144,7 @@ fe_args (int argc, char *argv[])
GError *error = NULL; GError *error = NULL;
GOptionContext *context; GOptionContext *context;
char *buffer; char *buffer;
const char *desktop_id = "net.zoite.Zoitechat";
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
@@ -220,6 +245,8 @@ fe_args (int argc, char *argv[])
} }
#ifdef WIN32 #ifdef WIN32
win32_set_gsettings_schema_dir ();
/* this is mainly for irc:// URL handling. When windows calls us from */ /* this is mainly for irc:// URL handling. When windows calls us from */
/* I.E, it doesn't give an option of "Start in" directory, like short */ /* I.E, it doesn't give an option of "Start in" directory, like short */
/* cuts can. So we have to set the current dir manually, to the path */ /* cuts can. So we have to set the current dir manually, to the path */
@@ -238,6 +265,10 @@ fe_args (int argc, char *argv[])
} }
#endif #endif
g_set_prgname (desktop_id);
#ifndef WIN32
gdk_set_program_class (desktop_id);
#endif
gtk_init (&argc, &argv); gtk_init (&argc, &argv);
#ifdef HAVE_GTK_MAC #ifdef HAVE_GTK_MAC
@@ -394,13 +425,32 @@ fe_dark_mode_is_enabled (void)
return fe_dark_mode_is_enabled_for (prefs.hex_gui_dark_mode); return fe_dark_mode_is_enabled_for (prefs.hex_gui_dark_mode);
} }
GtkStyle * InputStyle *
create_input_style (GtkStyle *style) create_input_style (InputStyle *style)
{ {
char buf[256]; char buf[256];
static int done_rc = FALSE; static int done_rc = FALSE;
#if HAVE_GTK3
static GtkCssProvider *input_css_provider = NULL;
static char *last_theme_name = NULL;
static gboolean last_dark_mode = FALSE;
static gboolean last_input_style = FALSE;
static gboolean last_colors_set = FALSE;
static guint16 last_fg_red;
static guint16 last_fg_green;
static guint16 last_fg_blue;
static guint16 last_bg_red;
static guint16 last_bg_green;
static guint16 last_bg_blue;
#endif
pango_font_description_free (style->font_desc); #if HAVE_GTK3
if (!style)
style = g_new0 (InputStyle, 1);
#endif
if (style->font_desc)
pango_font_description_free (style->font_desc);
style->font_desc = pango_font_description_from_string (prefs.hex_text_font); style->font_desc = pango_font_description_from_string (prefs.hex_text_font);
/* fall back */ /* fall back */
@@ -412,27 +462,159 @@ create_input_style (GtkStyle *style)
style->font_desc = pango_font_description_from_string ("sans 11"); style->font_desc = pango_font_description_from_string ("sans 11");
} }
if (prefs.hex_gui_input_style && !done_rc) if (prefs.hex_gui_input_style)
{ {
#if !HAVE_GTK3
if (!done_rc)
{
GtkSettings *settings = gtk_settings_get_default ();
char *theme_name;
/* gnome-themes-standard 3.20+ relies on images to do theming
* so we have to override that. */
g_object_get (settings, "gtk-theme-name", &theme_name, NULL);
if (g_str_has_prefix (theme_name, "Adwaita") || g_str_has_prefix (theme_name, "Yaru"))
gtk_rc_parse_string (adwaita_workaround_rc);
g_free (theme_name);
{
guint16 red;
guint16 green;
guint16 blue;
palette_color_get_rgb16 (&colors[COL_FG], &red, &green, &blue);
sprintf (buf, cursor_color_rc, (red >> 8), (green >> 8), (blue >> 8));
}
gtk_rc_parse_string (buf);
done_rc = TRUE;
}
#else
GtkSettings *settings = gtk_settings_get_default (); GtkSettings *settings = gtk_settings_get_default ();
GdkScreen *screen = gdk_screen_get_default ();
char *theme_name; char *theme_name;
char cursor_rc[sizeof (cursor_color_rc)];
char cursor_color[8];
const char *cursor_color_start = NULL;
guint16 fg_red;
guint16 fg_green;
guint16 fg_blue;
guint16 bg_red;
guint16 bg_green;
guint16 bg_blue;
gboolean dark_mode = fe_dark_mode_is_enabled ();
gboolean needs_reload;
/* gnome-themes-standard 3.20+ relies on images to do theming
* so we have to override that. */
g_object_get (settings, "gtk-theme-name", &theme_name, NULL); g_object_get (settings, "gtk-theme-name", &theme_name, NULL);
if (g_str_has_prefix (theme_name, "Adwaita") || g_str_has_prefix (theme_name, "Yaru"))
gtk_rc_parse_string (adwaita_workaround_rc); palette_color_get_rgb16 (&colors[COL_FG], &fg_red, &fg_green, &fg_blue);
palette_color_get_rgb16 (&colors[COL_BG], &bg_red, &bg_green, &bg_blue);
needs_reload = !done_rc
|| !last_input_style
|| last_dark_mode != dark_mode
|| g_strcmp0 (last_theme_name, theme_name) != 0
|| !last_colors_set
|| last_fg_red != fg_red
|| last_fg_green != fg_green
|| last_fg_blue != fg_blue
|| last_bg_red != bg_red
|| last_bg_green != bg_green
|| last_bg_blue != bg_blue;
if (needs_reload)
{
if (!input_css_provider)
input_css_provider = gtk_css_provider_new ();
g_snprintf (buf, sizeof (buf), "#%02x%02x%02x",
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8));
g_snprintf (cursor_rc, sizeof (cursor_rc), cursor_color_rc,
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8));
cursor_color_start = g_strstr_len (cursor_rc, -1, "cursor-color=\"");
if (cursor_color_start)
{
cursor_color_start += strlen ("cursor-color=\"");
g_strlcpy (cursor_color, cursor_color_start, sizeof (cursor_color));
cursor_color[7] = '\0';
}
else
{
g_strlcpy (cursor_color, buf, sizeof (cursor_color));
}
{
GString *css = g_string_new ("#zoitechat-inputbox {");
/* GTK3 equivalents for adwaita_workaround_rc/cursor_color_rc. */
if (adwaita_workaround_rc[0] != '\0'
&& (g_str_has_prefix (theme_name, "Adwaita")
|| g_str_has_prefix (theme_name, "Yaru")))
g_string_append (css, "background-image: none;");
g_string_append_printf (
css,
"background-color: #%02x%02x%02x;"
"color: #%02x%02x%02x;"
"caret-color: %s;"
"}"
"#zoitechat-inputbox text {"
"color: #%02x%02x%02x;"
"caret-color: %s;"
"}",
(bg_red >> 8), (bg_green >> 8), (bg_blue >> 8),
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8),
cursor_color,
(fg_red >> 8), (fg_green >> 8), (fg_blue >> 8),
cursor_color);
gtk_css_provider_load_from_data (input_css_provider, css->str, -1, NULL);
g_string_free (css, TRUE);
}
if (screen)
gtk_style_context_add_provider_for_screen (
screen,
GTK_STYLE_PROVIDER (input_css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
done_rc = TRUE;
last_input_style = TRUE;
last_dark_mode = dark_mode;
last_colors_set = TRUE;
last_fg_red = fg_red;
last_fg_green = fg_green;
last_fg_blue = fg_blue;
last_bg_red = bg_red;
last_bg_green = bg_green;
last_bg_blue = bg_blue;
g_free (last_theme_name);
last_theme_name = g_strdup (theme_name);
}
g_free (theme_name); g_free (theme_name);
#endif
done_rc = TRUE;
sprintf (buf, cursor_color_rc, (colors[COL_FG].red >> 8),
(colors[COL_FG].green >> 8), (colors[COL_FG].blue >> 8));
gtk_rc_parse_string (buf);
} }
#if HAVE_GTK3
else
{
GdkScreen *screen = gdk_screen_get_default ();
if (input_css_provider && screen)
{
gtk_style_context_remove_provider_for_screen (
screen,
GTK_STYLE_PROVIDER (input_css_provider));
}
g_clear_object (&input_css_provider);
g_clear_pointer (&last_theme_name, g_free);
done_rc = FALSE;
last_input_style = FALSE;
last_colors_set = FALSE;
}
#endif
#if !HAVE_GTK3
style->bg[GTK_STATE_NORMAL] = colors[COL_FG]; style->bg[GTK_STATE_NORMAL] = colors[COL_FG];
style->base[GTK_STATE_NORMAL] = colors[COL_BG]; style->base[GTK_STATE_NORMAL] = colors[COL_BG];
style->text[GTK_STATE_NORMAL] = colors[COL_FG]; style->text[GTK_STATE_NORMAL] = colors[COL_FG];
#endif
return style; return style;
} }
@@ -451,7 +633,11 @@ fe_init (void)
gtkosx_application_set_dock_icon_pixbuf (osx_app, pix_zoitechat); gtkosx_application_set_dock_icon_pixbuf (osx_app, pix_zoitechat);
#endif #endif
channelwin_pix = pixmap_load_from_file (prefs.hex_text_background); channelwin_pix = pixmap_load_from_file (prefs.hex_text_background);
#if HAVE_GTK3
input_style = create_input_style (input_style);
#else
input_style = create_input_style (gtk_style_new ()); input_style = create_input_style (gtk_style_new ());
#endif
settings = gtk_settings_get_default (); settings = gtk_settings_get_default ();
if (settings) if (settings)
@@ -1074,8 +1260,8 @@ fe_gui_info_ptr (session *sess, int info_type)
switch (info_type) switch (info_type)
{ {
case 0: /* native window pointer (for plugins) */ case 0: /* native window pointer (for plugins) */
#ifdef WIN32 #ifdef GDK_WINDOWING_WIN32
return gdk_win32_window_get_impl_hwnd (gtk_widget_get_window (sess->gui->window)); return gdk_win32_window_get_handle (gtk_widget_get_window (sess->gui->window));
#else #else
return sess->gui->window; return sess->gui->window;
#endif #endif

View File

@@ -32,6 +32,22 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <cairo.h> #include <cairo.h>
#ifndef HAVE_GTK3
#if GTK_MAJOR_VERSION >= 3
#define HAVE_GTK3 1
#else
#define HAVE_GTK3 0
#endif
#endif
#if !HAVE_GTK3
/* GtkWidget expansion APIs were introduced in GTK3. Keep GTK2 builds
* source-compatible by accepting the calls as no-ops.
*/
#define gtk_widget_set_hexpand(widget, expand) G_STMT_START { (void) (widget); (void) (expand); } G_STMT_END
#define gtk_widget_set_vexpand(widget, expand) G_STMT_START { (void) (widget); (void) (expand); } G_STMT_END
#endif
#ifdef HAVE_GTK_MAC #ifdef HAVE_GTK_MAC
#include <gtkosxapplication.h> #include <gtkosxapplication.h>
#endif #endif
@@ -48,6 +64,15 @@
#define flag_b flag_wid[7] #define flag_b flag_wid[7]
#define NUM_FLAG_WIDS 8 #define NUM_FLAG_WIDS 8
#if HAVE_GTK3
typedef struct _input_style
{
PangoFontDescription *font_desc;
} InputStyle;
#else
typedef GtkStyle InputStyle;
#endif
#ifdef HAVE_GTK_MAC #ifdef HAVE_GTK_MAC
extern GtkosxApplication *osx_app; extern GtkosxApplication *osx_app;
#endif #endif

View File

@@ -30,7 +30,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\common;$(ZoiteChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\common;$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings> <DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile> </ClCompile>
<Link> <Link>
@@ -42,7 +42,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\common;$(ZoiteChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\common;$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> <DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile> </ClCompile>
<Link> <Link>

View File

@@ -53,6 +53,19 @@
#include "textgui.h" #include "textgui.h"
#include "fkeys.h" #include "fkeys.h"
#if HAVE_GTK3
#define ICON_FKEYS_NEW "document-new"
#define ICON_FKEYS_DELETE "edit-delete"
#define ICON_FKEYS_CANCEL "dialog-cancel"
#define ICON_FKEYS_SAVE "document-save"
#endif
#if !HAVE_GTK3
#define ICON_FKEYS_NEW GTK_STOCK_NEW
#define ICON_FKEYS_DELETE GTK_STOCK_DELETE
#define ICON_FKEYS_CANCEL GTK_STOCK_CANCEL
#define ICON_FKEYS_SAVE GTK_STOCK_SAVE
#endif
static void replace_handle (GtkWidget * wid); static void replace_handle (GtkWidget * wid);
void key_check_replace_on_change (GtkEditable *editable, gpointer data); void key_check_replace_on_change (GtkEditable *editable, gpointer data);
void key_action_tab_clean (void); void key_action_tab_clean (void);
@@ -137,14 +150,77 @@ static int key_action_put_history (GtkWidget * wid, GdkEventKey * evt,
static GSList *keybind_list = NULL; static GSList *keybind_list = NULL;
static gsize
key_action_decode_escapes (const char *input, char *output)
{
gsize ii;
gsize oi = 0;
gsize len = strlen (input);
for (ii = 0; ii < len; ii++)
{
if (input[ii] != '\\')
{
output[oi++] = input[ii];
continue;
}
if (ii + 1 >= len)
{
output[oi++] = '\\';
break;
}
ii++;
switch (input[ii])
{
case 'n':
output[oi++] = '\n';
break;
case 'r':
output[oi++] = '\r';
break;
case 't':
output[oi++] = '\t';
break;
case '\\':
output[oi++] = '\\';
break;
case 'x':
if (ii + 2 < len && g_ascii_isxdigit (input[ii + 1]) &&
g_ascii_isxdigit (input[ii + 2]))
{
output[oi++] =
(g_ascii_xdigit_value (input[ii + 1]) << 4) |
g_ascii_xdigit_value (input[ii + 2]);
ii += 2;
}
else
{
output[oi++] = '\\';
output[oi++] = 'x';
}
break;
default:
output[oi++] = '\\';
output[oi++] = input[ii];
break;
}
}
output[oi] = 0;
return oi;
}
static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = { static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = {
{key_action_handle_command, "Run Command", {key_action_handle_command, "Run Command",
N_("The \002Run Command\002 action runs the data in Data 1 as if it had been typed into the entry box where you pressed the key sequence. Thus it can contain text (which will be sent to the channel/person), commands or user commands. When run all \002\\n\002 characters in Data 1 are used to deliminate separate commands so it is possible to run more than one command. If you want a \002\\\002 in the actual text run then enter \002\\\\\002")}, N_("The \002Run Command\002 action runs the data in Data 1 as if it had been typed into the entry box where you pressed the key sequence. Thus it can contain text (which will be sent to the channel/person), commands or user commands. Escapes in Data 1 are interpreted (for example \002\\n\002, \002\\r\002, \002\\t\002, \002\\xNN\002 and \002\\\\\002), so it is possible to run more than one command by using newlines.")},
{key_action_page_switch, "Change Page", {key_action_page_switch, "Change Page",
N_("The \002Change Page\002 command switches between pages in the notebook. Set Data 1 to the page you want to switch to. If Data 2 is set to anything then the switch will be relative to the current position. Set Data 1 to auto to switch to the page with the most recent and important activity (queries first, then channels with hilight, channels with dialogue, channels with other data)")}, N_("The \002Change Page\002 command switches between pages in the notebook. Set Data 1 to the page you want to switch to. If Data 2 is set to anything then the switch will be relative to the current position. Set Data 1 to auto to switch to the page with the most recent and important activity (queries first, then channels with hilight, channels with dialogue, channels with other data)")},
{key_action_insert, "Insert in Buffer", {key_action_insert, "Insert in Buffer",
N_("The \002Insert in Buffer\002 command will insert the contents of Data 1 into the entry where the key sequence was pressed at the current cursor position")}, N_("The \002Insert in Buffer\002 command will insert the contents of Data 1 into the entry where the key sequence was pressed at the current cursor position. Escapes in Data 1 are interpreted (for example \002\\n\002, \002\\r\002, \002\\t\002, \002\\xNN\002 and \002\\\\\002).")},
{key_action_scroll_page, "Scroll Page", {key_action_scroll_page, "Scroll Page",
N_("The \002Scroll Page\002 command scrolls the text widget up or down one page or one line. Set Data 1 to either Top, Bottom, Up, Down, +1 or -1.")}, N_("The \002Scroll Page\002 command scrolls the text widget up or down one page or one line. Set Data 1 to either Top, Bottom, Up, Down, +1 or -1.")},
{key_action_set_buffer, "Set Buffer", {key_action_set_buffer, "Set Buffer",
@@ -189,6 +265,7 @@ static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = {
"ACCEL=<Primary>k\nInsert in Buffer\nD1:\003\nD2!\n\n"\ "ACCEL=<Primary>k\nInsert in Buffer\nD1:\003\nD2!\n\n"\
"ACCEL=<Primary>i\nInsert in Buffer\nD1:\035\nD2!\n\n"\ "ACCEL=<Primary>i\nInsert in Buffer\nD1:\035\nD2!\n\n"\
"ACCEL=<Primary>u\nInsert in Buffer\nD1:\037\nD2!\n\n"\ "ACCEL=<Primary>u\nInsert in Buffer\nD1:\037\nD2!\n\n"\
"ACCEL=<Primary><Alt>s\nInsert in Buffer\nD1:\036\nD2!\n\n"\
"ACCEL=<Primary>r\nInsert in Buffer\nD1:\026\nD2!\n\n"\ "ACCEL=<Primary>r\nInsert in Buffer\nD1:\026\nD2!\n\n"\
"ACCEL=<Shift>Page_Down\nChange Selected Nick\nD1!\nD2!\n\n"\ "ACCEL=<Shift>Page_Down\nChange Selected Nick\nD1!\nD2!\n\n"\
"ACCEL=<Shift>Page_Up\nChange Selected Nick\nD1:Up\nD2!\n\n"\ "ACCEL=<Shift>Page_Up\nChange Selected Nick\nD1:Up\nD2!\n\n"\
@@ -676,7 +753,30 @@ key_dialog_treeview_new (GtkWidget *box)
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW(view))), g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW(view))),
"changed", G_CALLBACK (key_dialog_selection_changed), NULL); "changed", G_CALLBACK (key_dialog_selection_changed), NULL);
#if HAVE_GTK3
gtk_widget_set_name (view, "fkeys-treeview");
{
GtkCssProvider *provider = gtk_css_provider_new ();
GtkStyleContext *context = gtk_widget_get_style_context (view);
gtk_css_provider_load_from_data (
provider,
"treeview#fkeys-treeview row:nth-child(odd) {"
" background-color: @theme_base_color;"
"}"
"treeview#fkeys-treeview row:nth-child(even) {"
" background-color: shade(@theme_base_color, 0.96);"
"}",
-1,
NULL);
gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
}
#endif
#if !HAVE_GTK3
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
#endif
render = gtk_cell_renderer_accel_new (); render = gtk_cell_renderer_accel_new ();
g_object_set (render, "editable", TRUE, g_object_set (render, "editable", TRUE,
@@ -762,7 +862,7 @@ key_dialog_treeview_new (GtkWidget *box)
gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_column_set_resizable (col, TRUE);
gtk_container_add (GTK_CONTAINER (scroll), view); gtk_container_add (GTK_CONTAINER (scroll), view);
gtk_container_add (GTK_CONTAINER (box), scroll); gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
return view; return view;
} }
@@ -825,18 +925,23 @@ key_dialog_show ()
g_object_set_data (G_OBJECT (key_dialog), "view", view); g_object_set_data (G_OBJECT (key_dialog), "view", view);
g_object_set_data (G_OBJECT (key_dialog), "xtext", xtext); g_object_set_data (G_OBJECT (key_dialog), "xtext", xtext);
#if HAVE_GTK3
box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
box = gtk_hbutton_box_new (); box = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
#endif
gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (box), 5); gtk_container_set_border_width (GTK_CONTAINER (box), 5);
gtkutil_button (box, GTK_STOCK_NEW, NULL, key_dialog_add, gtkutil_button (box, ICON_FKEYS_NEW, NULL, key_dialog_add,
NULL, _("Add")); NULL, _("Add"));
gtkutil_button (box, GTK_STOCK_DELETE, NULL, key_dialog_delete, gtkutil_button (box, ICON_FKEYS_DELETE, NULL, key_dialog_delete,
NULL, _("Delete")); NULL, _("Delete"));
gtkutil_button (box, GTK_STOCK_CANCEL, NULL, key_dialog_close, gtkutil_button (box, ICON_FKEYS_CANCEL, NULL, key_dialog_close,
NULL, _("Cancel")); NULL, _("Cancel"));
gtkutil_button (box, GTK_STOCK_SAVE, NULL, key_dialog_save, gtkutil_button (box, ICON_FKEYS_SAVE, NULL, key_dialog_save,
NULL, _("Save")); NULL, _("Save"));
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view))); store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
@@ -1121,38 +1226,16 @@ static int
key_action_handle_command (GtkWidget * wid, GdkEventKey * evt, char *d1, key_action_handle_command (GtkWidget * wid, GdkEventKey * evt, char *d1,
char *d2, struct session *sess) char *d2, struct session *sess)
{ {
int ii, oi, len; char *out;
char out[2048], d = 0;
if (!d1) if (!d1)
return 0; return 0;
len = strlen (d1); out = g_malloc (strlen (d1) + 1);
key_action_decode_escapes (d1, out);
/* Replace each "\n" substring with '\n' */
for (ii = oi = 0; ii < len; ii++)
{
d = d1[ii];
if (d == '\\')
{
ii++;
d = d1[ii];
if (d == 'n')
out[oi++] = '\n';
else if (d == '\\')
out[oi++] = '\\';
else
{
out[oi++] = '\\';
out[oi++] = d;
}
continue;
}
out[oi++] = d;
}
out[oi] = 0;
handle_multiline (sess, out, 0, 0); handle_multiline (sess, out, 0, 0);
g_free (out);
return 0; return 0;
} }
@@ -1234,13 +1317,19 @@ key_action_insert (GtkWidget * wid, GdkEventKey * evt, char *d1, char *d2,
struct session *sess) struct session *sess)
{ {
int tmp_pos; int tmp_pos;
char *decoded;
gsize decoded_len;
if (!d1) if (!d1)
return 1; return 1;
decoded = g_malloc (strlen (d1) + 1);
decoded_len = key_action_decode_escapes (d1, decoded);
tmp_pos = SPELL_ENTRY_GET_POS (wid); tmp_pos = SPELL_ENTRY_GET_POS (wid);
SPELL_ENTRY_INSERT (wid, d1, strlen (d1), &tmp_pos); SPELL_ENTRY_INSERT (wid, decoded, decoded_len, &tmp_pos);
SPELL_ENTRY_SET_POS (wid, tmp_pos); SPELL_ENTRY_SET_POS (wid, tmp_pos);
g_free (decoded);
return 2; return 2;
} }

View File

@@ -62,6 +62,294 @@ struct file_req
int flags; /* FRF_* flags */ int flags; /* FRF_* flags */
}; };
#if HAVE_GTK3
const char *
gtkutil_icon_name_from_stock (const char *stock_name)
{
static const struct
{
const char *stock;
const char *icon;
} icon_map[] = {
{ "gtk-new", "document-new" },
{ "gtk-open", "document-open" },
{ "gtk-revert-to-saved", "document-open" },
{ "gtk-save", "document-save" },
{ "gtk-save-as", "document-save-as" },
{ "gtk-add", "list-add" },
{ "gtk-cancel", "dialog-cancel" },
{ "gtk-ok", "dialog-ok" },
{ "gtk-no", "dialog-cancel" },
{ "gtk-yes", "dialog-ok" },
{ "gtk-apply", "dialog-apply" },
{ "gtk-dialog-error", "dialog-error" },
{ "gtk-copy", "edit-copy" },
{ "gtk-delete", "edit-delete" },
{ "gtk-remove", "list-remove" },
{ "gtk-clear", "edit-clear" },
{ "gtk-redo", "edit-redo" },
{ "gtk-find", "edit-find" },
{ "gtk-justify-left", "edit-find" },
{ "gtk-refresh", "view-refresh" },
{ "gtk-go-back", "go-previous" },
{ "gtk-go-forward", "go-next" },
{ "gtk-index", "view-list" },
{ "gtk-jump-to", "go-jump" },
{ "gtk-media-play", "media-playback-start" },
{ "gtk-preferences", "preferences-system" },
{ "gtk-help", "help-browser" },
{ "gtk-about", "help-about" },
{ "gtk-close", "window-close" },
{ "gtk-quit", "application-exit" },
{ "gtk-connect", "network-connect" },
{ "gtk-disconnect", "network-disconnect" },
{ "gtk-network", "network-workgroup" },
{ "gtk-spell-check", "tools-check-spelling" },
};
size_t i;
if (!stock_name)
return NULL;
for (i = 0; i < G_N_ELEMENTS (icon_map); i++)
{
if (strcmp (stock_name, icon_map[i].stock) == 0)
return icon_map[i].icon;
}
return stock_name;
}
#endif
GtkWidget *
gtkutil_image_new_from_stock (const char *stock, GtkIconSize size)
{
#if HAVE_GTK3
const char *icon_name = gtkutil_icon_name_from_stock (stock);
return gtk_image_new_from_icon_name (icon_name, size);
#elif !HAVE_GTK3
return gtk_image_new_from_stock (stock, size);
#endif
}
GtkWidget *
gtkutil_button_new_from_stock (const char *stock, const char *label)
{
#if HAVE_GTK3
GtkWidget *button = label ? gtk_button_new_with_mnemonic (label) : gtk_button_new ();
if (stock)
{
GtkWidget *image = gtkutil_image_new_from_stock (stock, GTK_ICON_SIZE_BUTTON);
if (image)
{
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_button_set_always_show_image (GTK_BUTTON (button), TRUE);
}
}
return button;
#elif !HAVE_GTK3
if (stock)
return gtk_button_new_from_stock (stock);
if (label)
return gtk_button_new_with_mnemonic (label);
return gtk_button_new ();
#endif
}
#if HAVE_GTK3
void
gtkutil_append_font_css (GString *css, const PangoFontDescription *font_desc)
{
PangoFontMask mask;
if (!font_desc)
return;
mask = pango_font_description_get_set_fields (font_desc);
if (mask & PANGO_FONT_MASK_FAMILY)
{
const char *family = pango_font_description_get_family (font_desc);
if (family && *family)
g_string_append_printf (css, " font-family: \"%s\";", family);
}
if (mask & PANGO_FONT_MASK_STYLE)
{
const char *style = "normal";
switch (pango_font_description_get_style (font_desc))
{
case PANGO_STYLE_ITALIC:
style = "italic";
break;
case PANGO_STYLE_OBLIQUE:
style = "oblique";
break;
default:
style = "normal";
break;
}
g_string_append_printf (css, " font-style: %s;", style);
}
if (mask & PANGO_FONT_MASK_VARIANT)
{
const char *variant = "normal";
if (pango_font_description_get_variant (font_desc) == PANGO_VARIANT_SMALL_CAPS)
variant = "small-caps";
g_string_append_printf (css, " font-variant: %s;", variant);
}
if (mask & PANGO_FONT_MASK_WEIGHT)
{
int weight = (int) pango_font_description_get_weight (font_desc);
if (weight < 100)
weight = 100;
if (weight > 900)
weight = 900;
g_string_append_printf (css, " font-weight: %d;", weight);
}
if (mask & PANGO_FONT_MASK_STRETCH)
{
const char *stretch = "normal";
switch (pango_font_description_get_stretch (font_desc))
{
case PANGO_STRETCH_ULTRA_CONDENSED:
stretch = "ultra-condensed";
break;
case PANGO_STRETCH_EXTRA_CONDENSED:
stretch = "extra-condensed";
break;
case PANGO_STRETCH_CONDENSED:
stretch = "condensed";
break;
case PANGO_STRETCH_SEMI_CONDENSED:
stretch = "semi-condensed";
break;
case PANGO_STRETCH_SEMI_EXPANDED:
stretch = "semi-expanded";
break;
case PANGO_STRETCH_EXPANDED:
stretch = "expanded";
break;
case PANGO_STRETCH_EXTRA_EXPANDED:
stretch = "extra-expanded";
break;
case PANGO_STRETCH_ULTRA_EXPANDED:
stretch = "ultra-expanded";
break;
default:
stretch = "normal";
break;
}
g_string_append_printf (css, " font-stretch: %s;", stretch);
}
if (mask & PANGO_FONT_MASK_SIZE)
{
double size = (double) pango_font_description_get_size (font_desc) / PANGO_SCALE;
char size_buf[G_ASCII_DTOSTR_BUF_SIZE];
const char *unit = "pt";
if (pango_font_description_get_size_is_absolute (font_desc))
unit = "px";
g_ascii_formatd (size_buf, sizeof (size_buf), "%.2f", size);
g_string_append_printf (css, " font-size: %s%s;", size_buf, unit);
}
}
void
gtkutil_apply_palette (GtkWidget *widget, const GdkRGBA *bg, const GdkRGBA *fg,
const PangoFontDescription *font_desc)
#else
void
gtkutil_apply_palette (GtkWidget *widget, const GdkColor *bg, const GdkColor *fg,
const PangoFontDescription *font_desc)
#endif
{
if (!widget)
return;
#if HAVE_GTK3
{
static const char *class_name = "zoitechat-palette";
GtkStyleContext *context = gtk_widget_get_style_context (widget);
GtkCssProvider *provider = g_object_get_data (G_OBJECT (widget),
"zoitechat-palette-provider");
gboolean new_provider = FALSE;
GString *css;
gchar *bg_color = NULL;
gchar *fg_color = NULL;
if (!bg && !fg && !font_desc)
{
gtk_style_context_remove_class (context, class_name);
if (provider)
{
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
g_object_set_data (G_OBJECT (widget), "zoitechat-palette-provider", NULL);
}
return;
}
if (!provider)
{
provider = gtk_css_provider_new ();
g_object_set_data_full (G_OBJECT (widget), "zoitechat-palette-provider",
provider, g_object_unref);
new_provider = TRUE;
}
css = g_string_new (".");
g_string_append (css, class_name);
g_string_append (css, " {");
if (bg)
{
bg_color = gdk_rgba_to_string (bg);
g_string_append_printf (css, " background-color: %s;", bg_color);
}
if (fg)
{
fg_color = gdk_rgba_to_string (fg);
g_string_append_printf (css, " color: %s;", fg_color);
}
gtkutil_append_font_css (css, font_desc);
g_string_append (css, " }");
gtk_css_provider_load_from_data (provider, css->str, -1, NULL);
if (new_provider)
{
gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
gtk_style_context_add_class (context, class_name);
g_string_free (css, TRUE);
g_free (bg_color);
g_free (fg_color);
}
#else
gtk_widget_modify_base (widget, GTK_STATE_NORMAL, bg);
gtk_widget_modify_text (widget, GTK_STATE_NORMAL, fg);
gtk_widget_modify_font (widget, (PangoFontDescription *) font_desc);
#endif
}
static void static void
gtkutil_file_req_destroy (GtkWidget * wid, struct file_req *freq) gtkutil_file_req_destroy (GtkWidget * wid, struct file_req *freq)
{ {
@@ -74,6 +362,12 @@ gtkutil_check_file (char *filename, struct file_req *freq)
{ {
int axs = FALSE; int axs = FALSE;
if (filename == NULL || filename[0] == '\0')
{
fe_message (_("No file selected."), FE_MSG_ERROR);
return;
}
GFile *file = g_file_new_for_path (filename); GFile *file = g_file_new_for_path (filename);
if (freq->flags & FRF_WRITE) if (freq->flags & FRF_WRITE)
@@ -137,10 +431,9 @@ gtkutil_check_file (char *filename, struct file_req *freq)
} }
static void static void
gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq) gtkutil_file_req_done_chooser (GtkFileChooser *fs, struct file_req *freq)
{ {
GSList *files, *cur; GSList *files, *cur;
GtkFileChooser *fs = GTK_FILE_CHOOSER (freq->dialog);
if (freq->flags & FRF_MULTIPLE) if (freq->flags & FRF_MULTIPLE)
{ {
@@ -165,11 +458,21 @@ gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
else else
{ {
gchar *filename = gtk_file_chooser_get_filename (fs); gchar *filename = gtk_file_chooser_get_filename (fs);
gtkutil_check_file (gtk_file_chooser_get_filename (fs), freq); if (filename != NULL)
g_free (filename); {
gtkutil_check_file (filename, freq);
g_free (filename);
}
} }
} }
}
static void
gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
{
gtkutil_file_req_done_chooser (GTK_FILE_CHOOSER (freq->dialog), freq);
/* this should call the "destroy" cb, where we free(freq) */ /* this should call the "destroy" cb, where we free(freq) */
gtk_widget_destroy (freq->dialog); gtk_widget_destroy (freq->dialog);
} }
@@ -177,18 +480,42 @@ gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
static void static void
gtkutil_file_req_response (GtkWidget *dialog, gint res, struct file_req *freq) gtkutil_file_req_response (GtkWidget *dialog, gint res, struct file_req *freq)
{ {
switch (res) if (res == GTK_RESPONSE_ACCEPT)
{ {
case GTK_RESPONSE_ACCEPT:
gtkutil_file_req_done (dialog, freq); gtkutil_file_req_done (dialog, freq);
break; return;
case GTK_RESPONSE_CANCEL:
/* this should call the "destroy" cb, where we free(freq) */
gtk_widget_destroy (freq->dialog);
} }
/* this should call the "destroy" cb, where we free(freq) */
gtk_widget_destroy (dialog);
} }
#if defined (WIN32) && HAVE_GTK3
static gboolean
gtkutil_native_dialog_unref_idle (gpointer native)
{
g_object_unref (native);
return G_SOURCE_REMOVE;
}
static void
gtkutil_native_file_req_response (GtkNativeDialog *dialog, gint res, struct file_req *freq)
{
if (res == GTK_RESPONSE_ACCEPT)
gtkutil_file_req_done_chooser (GTK_FILE_CHOOSER (dialog), freq);
/* Match gtk dialog flow by always sending NULL to indicate completion. */
freq->callback (freq->userdata, NULL);
g_free (freq);
/*
* Defer unref until idle to avoid disposing the native chooser while
* still in the button-release signal stack on Windows.
*/
g_idle_add (gtkutil_native_dialog_unref_idle, dialog);
}
#endif
void void
gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *userdata, char *filter, char *extensions, gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *userdata, char *filter, char *extensions,
int flags) int flags)
@@ -196,27 +523,124 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
struct file_req *freq; struct file_req *freq;
GtkWidget *dialog; GtkWidget *dialog;
GtkFileFilter *filefilter; GtkFileFilter *filefilter;
extern char *get_xdir_fs (void);
char *token; char *token;
char *tokenbuffer; char *tokenbuffer;
const char *xdir;
GtkWindow *effective_parent = parent;
extern GtkWidget *parent_window;
if (effective_parent == NULL && parent_window != NULL)
effective_parent = GTK_WINDOW (parent_window);
xdir = get_xdir ();
#if defined (WIN32) && HAVE_GTK3
{
GtkFileChooserNative *native = gtk_file_chooser_native_new (
title,
effective_parent,
(flags & FRF_CHOOSEFOLDER) ? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER :
((flags & FRF_WRITE) ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN),
(flags & FRF_WRITE) ? _("_Save") : _("_Open"),
_("_Cancel"));
GtkFileChooser *native_chooser = GTK_FILE_CHOOSER (native);
if (flags & FRF_MULTIPLE)
gtk_file_chooser_set_select_multiple (native_chooser, TRUE);
if (flags & FRF_WRITE && !(flags & FRF_NOASKOVERWRITE))
gtk_file_chooser_set_do_overwrite_confirmation (native_chooser, TRUE);
if ((flags & FRF_EXTENSIONS || flags & FRF_MIMETYPES) && extensions != NULL)
{
GtkFileFilter *native_filter = gtk_file_filter_new ();
char *native_tokenbuffer = g_strdup (extensions);
char *native_token = strtok (native_tokenbuffer, ";");
while (native_token != NULL)
{
if (flags & FRF_EXTENSIONS)
gtk_file_filter_add_pattern (native_filter, native_token);
else
gtk_file_filter_add_mime_type (native_filter, native_token);
native_token = strtok (NULL, ";");
}
g_free (native_tokenbuffer);
gtk_file_chooser_set_filter (native_chooser, native_filter);
}
if (filter && filter[0] && (flags & FRF_FILTERISINITIAL))
{
if (flags & FRF_WRITE)
{
char temp[1024];
path_part (filter, temp, sizeof (temp));
if (temp[0] && g_file_test (temp, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (native_chooser, temp);
else if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (native_chooser, xdir);
gtk_file_chooser_set_current_name (native_chooser, file_part (filter));
}
else
{
if (g_file_test (filter, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (native_chooser, filter);
else if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (native_chooser, xdir);
}
}
else if (!(flags & FRF_RECENTLYUSED))
{
if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (native_chooser, xdir);
}
freq = g_new (struct file_req, 1);
freq->dialog = NULL;
freq->flags = flags;
freq->callback = callback;
freq->userdata = userdata;
g_signal_connect (native, "response",
G_CALLBACK (gtkutil_native_file_req_response), freq);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (native));
return;
}
#endif
if (flags & FRF_WRITE) if (flags & FRF_WRITE)
{ {
#if HAVE_GTK3
dialog = gtk_file_chooser_dialog_new (title, NULL,
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Save"), GTK_RESPONSE_ACCEPT,
NULL);
#elif !HAVE_GTK3
dialog = gtk_file_chooser_dialog_new (title, NULL, dialog = gtk_file_chooser_dialog_new (title, NULL,
GTK_FILE_CHOOSER_ACTION_SAVE, GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL); NULL);
#endif
if (!(flags & FRF_NOASKOVERWRITE)) if (!(flags & FRF_NOASKOVERWRITE))
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
} }
else else
#if HAVE_GTK3
dialog = gtk_file_chooser_dialog_new (title, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Open"), GTK_RESPONSE_ACCEPT,
NULL);
#elif !HAVE_GTK3
dialog = gtk_file_chooser_dialog_new (title, NULL, dialog = gtk_file_chooser_dialog_new (title, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL); NULL);
#endif
if (filter && filter[0] && (flags & FRF_FILTERISINITIAL)) if (filter && filter[0] && (flags & FRF_FILTERISINITIAL))
{ {
@@ -224,14 +648,25 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
{ {
char temp[1024]; char temp[1024];
path_part (filter, temp, sizeof (temp)); path_part (filter, temp, sizeof (temp));
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), temp); if (temp[0] && g_file_test (temp, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), temp);
else if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), xdir);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), file_part (filter)); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), file_part (filter));
} }
else else
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), filter); {
if (g_file_test (filter, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), filter);
else if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), xdir);
}
} }
else if (!(flags & FRF_RECENTLYUSED)) else if (!(flags & FRF_RECENTLYUSED))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), get_xdir ()); {
if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), xdir);
}
if (flags & FRF_MULTIPLE) if (flags & FRF_MULTIPLE)
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
@@ -257,8 +692,14 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filefilter); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filefilter);
} }
gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), get_xdir (), NULL); if (xdir && xdir[0] && g_file_test (xdir, G_FILE_TEST_IS_DIR))
{
GError *shortcut_error = NULL;
gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), xdir, &shortcut_error);
if (shortcut_error)
g_error_free (shortcut_error);
}
freq = g_new (struct file_req, 1); freq = g_new (struct file_req, 1);
freq->dialog = dialog; freq->dialog = dialog;
freq->flags = flags; freq->flags = flags;
@@ -270,12 +711,12 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
g_signal_connect (G_OBJECT (dialog), "destroy", g_signal_connect (G_OBJECT (dialog), "destroy",
G_CALLBACK (gtkutil_file_req_destroy), (gpointer) freq); G_CALLBACK (gtkutil_file_req_destroy), (gpointer) freq);
if (parent) if (effective_parent)
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); gtk_window_set_transient_for (GTK_WINDOW (dialog), effective_parent);
if (flags & FRF_MODAL) if (flags & FRF_MODAL)
{ {
g_assert (parent); g_assert (effective_parent);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
} }
@@ -355,10 +796,17 @@ fe_get_str (char *msg, char *def, void *callback, void *userdata)
GtkWidget *label; GtkWidget *label;
extern GtkWidget *parent_window; extern GtkWidget *parent_window;
#if HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (msg, NULL, 0,
_("_Cancel"), GTK_RESPONSE_REJECT,
_("_OK"), GTK_RESPONSE_ACCEPT,
NULL);
#elif !HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (msg, NULL, 0, dialog = gtk_dialog_new_with_buttons (msg, NULL, 0,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL); NULL);
#endif
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE); gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE);
@@ -372,7 +820,7 @@ fe_get_str (char *msg, char *def, void *callback, void *userdata)
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
} }
hbox = gtk_hbox_new (TRUE, 0); hbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, TRUE, 0);
g_object_set_data (G_OBJECT (dialog), "cb", callback); g_object_set_data (G_OBJECT (dialog), "cb", callback);
g_object_set_data (G_OBJECT (dialog), "ud", userdata); g_object_set_data (G_OBJECT (dialog), "ud", userdata);
@@ -450,15 +898,22 @@ fe_get_int (char *msg, int def, void *callback, void *userdata)
GtkAdjustment *adj; GtkAdjustment *adj;
extern GtkWidget *parent_window; extern GtkWidget *parent_window;
#if HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (msg, NULL, 0,
_("_Cancel"), GTK_RESPONSE_REJECT,
_("_OK"), GTK_RESPONSE_ACCEPT,
NULL);
#elif !HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (msg, NULL, 0, dialog = gtk_dialog_new_with_buttons (msg, NULL, 0,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL); NULL);
#endif
gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE); gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
hbox = gtk_hbox_new (TRUE, 0); hbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, TRUE, 0);
g_object_set_data (G_OBJECT (dialog), "cb", callback); g_object_set_data (G_OBJECT (dialog), "cb", callback);
g_object_set_data (G_OBJECT (dialog), "ud", userdata); g_object_set_data (G_OBJECT (dialog), "ud", userdata);
@@ -490,10 +945,17 @@ fe_get_bool (char *title, char *prompt, void *callback, void *userdata)
GtkWidget *prompt_label; GtkWidget *prompt_label;
extern GtkWidget *parent_window; extern GtkWidget *parent_window;
#if HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (title, NULL, 0,
_("_No"), GTK_RESPONSE_REJECT,
_("_Yes"), GTK_RESPONSE_ACCEPT,
NULL);
#elif !HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (title, NULL, 0, dialog = gtk_dialog_new_with_buttons (title, NULL, 0,
GTK_STOCK_NO, GTK_RESPONSE_REJECT, GTK_STOCK_NO, GTK_RESPONSE_REJECT,
GTK_STOCK_YES, GTK_RESPONSE_ACCEPT, GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
NULL); NULL);
#endif
gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE); gtk_box_set_homogeneous (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), TRUE);
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
@@ -523,20 +985,49 @@ gtkutil_button (GtkWidget *box, char *stock, char *tip, void *callback,
if (labeltext) if (labeltext)
{ {
gtk_button_set_label (GTK_BUTTON (wid), labeltext); gtk_button_set_label (GTK_BUTTON (wid), labeltext);
gtk_button_set_image (GTK_BUTTON (wid), gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU)); img = NULL;
#if HAVE_GTK3
if (stock)
img = gtkutil_image_new_from_stock (stock, GTK_ICON_SIZE_BUTTON);
#endif
#if !HAVE_GTK3
if (stock)
img = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_BUTTON);
#endif
if (img)
{
gtk_button_set_image (GTK_BUTTON (wid), img);
#if HAVE_GTK3
gtk_button_set_always_show_image (GTK_BUTTON (wid), TRUE);
#endif
}
gtk_button_set_use_underline (GTK_BUTTON (wid), TRUE); gtk_button_set_use_underline (GTK_BUTTON (wid), TRUE);
if (box) if (box)
gtk_container_add (GTK_CONTAINER (box), wid); gtk_container_add (GTK_CONTAINER (box), wid);
} }
else else
{ {
bbox = gtk_hbox_new (0, 0); bbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
gtk_container_add (GTK_CONTAINER (wid), bbox); gtk_container_add (GTK_CONTAINER (wid), bbox);
gtk_widget_show (bbox); gtk_widget_show (bbox);
img = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU); img = NULL;
gtk_container_add (GTK_CONTAINER (bbox), img); #if HAVE_GTK3
gtk_widget_show (img); if (stock)
img = gtkutil_image_new_from_stock (stock, GTK_ICON_SIZE_BUTTON);
#endif
#if !HAVE_GTK3
if (stock)
img = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_BUTTON);
#endif
if (img)
{
gtk_container_add (GTK_CONTAINER (bbox), img);
gtk_widget_show (img);
#if HAVE_GTK3
gtk_button_set_always_show_image (GTK_BUTTON (wid), TRUE);
#endif
}
gtk_box_pack_start (GTK_BOX (box), wid, 0, 0, 0); gtk_box_pack_start (GTK_BOX (box), wid, 0, 0, 0);
} }
@@ -660,8 +1151,15 @@ gtkutil_treeview_new (GtkWidget *box, GtkTreeModel *model,
win = gtk_scrolled_window_new (0, 0); win = gtk_scrolled_window_new (0, 0);
gtk_container_add (GTK_CONTAINER (box), win); gtk_container_add (GTK_CONTAINER (box), win);
if (GTK_IS_BOX (box))
{
gtk_box_set_child_packing (GTK_BOX (box), win, TRUE, TRUE, 0,
GTK_PACK_START);
}
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (win), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (win),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand (win, TRUE);
gtk_widget_set_hexpand (win, TRUE);
gtk_widget_show (win); gtk_widget_show (win);
view = gtk_tree_view_new_with_model (model); view = gtk_tree_view_new_with_model (model);
@@ -752,11 +1250,13 @@ gtkutil_treeview_get_selected (GtkTreeView *view, GtkTreeIter *iter_ret, ...)
gboolean gboolean
gtkutil_tray_icon_supported (GtkWindow *window) gtkutil_tray_icon_supported (GtkWindow *window)
{ {
#ifndef GDK_WINDOWING_X11 #ifdef GDK_WINDOWING_X11
return TRUE;
#else
GdkScreen *screen = gtk_window_get_screen (window); GdkScreen *screen = gtk_window_get_screen (window);
GdkDisplay *display = gdk_screen_get_display (screen); GdkDisplay *display = gdk_screen_get_display (screen);
#if HAVE_GTK3
if (!GDK_IS_X11_DISPLAY (display))
return FALSE;
#endif
int screen_number = gdk_screen_get_number (screen); int screen_number = gdk_screen_get_number (screen);
Display *xdisplay = gdk_x11_display_get_xdisplay (display); Display *xdisplay = gdk_x11_display_get_xdisplay (display);
char *selection_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d", screen_number); char *selection_name = g_strdup_printf ("_NET_SYSTEM_TRAY_S%d", screen_number);
@@ -772,6 +1272,8 @@ gtkutil_tray_icon_supported (GtkWindow *window)
g_free (selection_name); g_free (selection_name);
return (tray_window != None); return (tray_window != None);
#else
return TRUE;
#endif #endif
} }
@@ -805,3 +1307,95 @@ gtkutil_find_font (const char *fontname)
return FALSE; return FALSE;
} }
#endif #endif
GtkWidget *
gtkutil_box_new (GtkOrientation orientation, gboolean homogeneous, gint spacing)
{
#if HAVE_GTK3
GtkWidget *box = gtk_box_new (orientation, spacing);
gtk_box_set_homogeneous (GTK_BOX (box), homogeneous);
return box;
#elif !HAVE_GTK3
if (orientation == GTK_ORIENTATION_HORIZONTAL)
return gtk_hbox_new (homogeneous, spacing);
return gtk_vbox_new (homogeneous, spacing);
#endif
}
GtkWidget *
gtkutil_grid_new (guint rows, guint columns, gboolean homogeneous)
{
#if HAVE_GTK3
GtkWidget *grid = gtk_grid_new ();
gtk_grid_set_row_homogeneous (GTK_GRID (grid), homogeneous);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), homogeneous);
return grid;
#elif !HAVE_GTK3
return gtk_table_new (rows, columns, homogeneous);
#endif
}
#if HAVE_GTK3
static GtkAlign
gtkutil_align_from_options (GtkutilAttachOptions options, GtkAlign default_align)
{
if (options & GTKUTIL_ATTACH_FILL)
return GTK_ALIGN_FILL;
return default_align;
}
#endif
static gboolean
gtkutil_expansion_from_options (GtkutilAttachOptions options, gboolean default_expand)
{
if (options & GTKUTIL_ATTACH_EXPAND)
return TRUE;
return default_expand;
}
void
gtkutil_grid_attach (GtkWidget *table, GtkWidget *child,
guint left_attach, guint right_attach,
guint top_attach, guint bottom_attach,
GtkutilAttachOptions xoptions, GtkutilAttachOptions yoptions,
guint xpad, guint ypad)
{
#if HAVE_GTK3
gtk_widget_set_hexpand (child, gtkutil_expansion_from_options (xoptions, FALSE));
gtk_widget_set_vexpand (child, gtkutil_expansion_from_options (yoptions, FALSE));
gtk_widget_set_halign (child, gtkutil_align_from_options (xoptions, GTK_ALIGN_CENTER));
gtk_widget_set_valign (child, gtkutil_align_from_options (yoptions, GTK_ALIGN_CENTER));
gtk_widget_set_margin_start (child, xpad);
gtk_widget_set_margin_end (child, xpad);
gtk_widget_set_margin_top (child, ypad);
gtk_widget_set_margin_bottom (child, ypad);
gtk_grid_attach (GTK_GRID (table), child, left_attach, top_attach,
right_attach - left_attach, bottom_attach - top_attach);
#elif !HAVE_GTK3
gtk_table_attach (GTK_TABLE (table), child, left_attach, right_attach,
top_attach, bottom_attach, xoptions, yoptions, xpad, ypad);
#endif
}
void
gtkutil_grid_attach_defaults (GtkWidget *table, GtkWidget *child,
guint left_attach, guint right_attach,
guint top_attach, guint bottom_attach)
{
#if HAVE_GTK3
gtk_widget_set_hexpand (child, TRUE);
gtk_widget_set_vexpand (child, TRUE);
gtk_widget_set_halign (child, GTK_ALIGN_FILL);
gtk_widget_set_valign (child, GTK_ALIGN_FILL);
gtk_grid_attach (GTK_GRID (table), child, left_attach, top_attach,
right_attach - left_attach, bottom_attach - top_attach);
#elif !HAVE_GTK3
gtk_table_attach_defaults (GTK_TABLE (table), child, left_attach, right_attach,
top_attach, bottom_attach);
#endif
}

View File

@@ -22,14 +22,42 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "../common/fe.h" #include "../common/fe.h"
#include "palette.h"
typedef void (*filereqcallback) (void *, char *file); typedef void (*filereqcallback) (void *, char *file);
#ifndef HAVE_GTK3
#if GTK_MAJOR_VERSION >= 3
#define HAVE_GTK3 1
#else
#define HAVE_GTK3 0
#endif
#endif
#if HAVE_GTK3
typedef enum
{
GTKUTIL_ATTACH_EXPAND = 1 << 0,
GTKUTIL_ATTACH_SHRINK = 1 << 1,
GTKUTIL_ATTACH_FILL = 1 << 2
} GtkutilAttachOptions;
#else
typedef GtkAttachOptions GtkutilAttachOptions;
#define GTKUTIL_ATTACH_EXPAND GTK_EXPAND
#define GTKUTIL_ATTACH_SHRINK GTK_SHRINK
#define GTKUTIL_ATTACH_FILL GTK_FILL
#endif
void gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *userdata, char *filter, char *extensions, int flags); void gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *userdata, char *filter, char *extensions, int flags);
void gtkutil_destroy (GtkWidget * igad, GtkWidget * dgad); void gtkutil_destroy (GtkWidget * igad, GtkWidget * dgad);
void gtkutil_destroy_on_esc (GtkWidget *win); void gtkutil_destroy_on_esc (GtkWidget *win);
GtkWidget *gtkutil_button (GtkWidget *box, char *stock, char *tip, void *callback, GtkWidget *gtkutil_button (GtkWidget *box, char *stock, char *tip, void *callback,
void *userdata, char *labeltext); void *userdata, char *labeltext);
GtkWidget *gtkutil_image_new_from_stock (const char *stock, GtkIconSize size);
GtkWidget *gtkutil_button_new_from_stock (const char *stock, const char *label);
#if HAVE_GTK3
const char *gtkutil_icon_name_from_stock (const char *stock_name);
#endif
void gtkutil_label_new (char *text, GtkWidget * box); void gtkutil_label_new (char *text, GtkWidget * box);
GtkWidget *gtkutil_entry_new (int max, GtkWidget * box, void *callback, GtkWidget *gtkutil_entry_new (int max, GtkWidget * box, void *callback,
gpointer userdata); gpointer userdata);
@@ -44,6 +72,24 @@ gboolean gtkutil_treemodel_string_to_iter (GtkTreeModel *model, gchar *pathstr,
gboolean gtkutil_treeview_get_selected_iter (GtkTreeView *view, GtkTreeIter *iter_ret); gboolean gtkutil_treeview_get_selected_iter (GtkTreeView *view, GtkTreeIter *iter_ret);
gboolean gtkutil_treeview_get_selected (GtkTreeView *view, GtkTreeIter *iter_ret, ...); gboolean gtkutil_treeview_get_selected (GtkTreeView *view, GtkTreeIter *iter_ret, ...);
gboolean gtkutil_tray_icon_supported (GtkWindow *window); gboolean gtkutil_tray_icon_supported (GtkWindow *window);
GtkWidget *gtkutil_box_new (GtkOrientation orientation, gboolean homogeneous, gint spacing);
GtkWidget *gtkutil_grid_new (guint rows, guint columns, gboolean homogeneous);
void gtkutil_grid_attach (GtkWidget *table, GtkWidget *child,
guint left_attach, guint right_attach,
guint top_attach, guint bottom_attach,
GtkutilAttachOptions xoptions, GtkutilAttachOptions yoptions,
guint xpad, guint ypad);
void gtkutil_grid_attach_defaults (GtkWidget *table, GtkWidget *child,
guint left_attach, guint right_attach,
guint top_attach, guint bottom_attach);
#if HAVE_GTK3
void gtkutil_apply_palette (GtkWidget *widget, const GdkRGBA *bg, const GdkRGBA *fg,
const PangoFontDescription *font_desc);
void gtkutil_append_font_css (GString *css, const PangoFontDescription *font_desc);
#else
void gtkutil_apply_palette (GtkWidget *widget, const GdkColor *bg, const GdkColor *fg,
const PangoFontDescription *font_desc);
#endif
#if defined (WIN32) || defined (__APPLE__) #if defined (WIN32) || defined (__APPLE__)
gboolean gtkutil_find_font (const char *fontname); gboolean gtkutil_find_font (const char *fontname);

View File

@@ -31,6 +31,17 @@
#include "gtkutil.h" #include "gtkutil.h"
#include "maingui.h" #include "maingui.h"
#if HAVE_GTK3
#define ICON_IGNORE_NEW "document-new"
#define ICON_IGNORE_DELETE "edit-delete"
#define ICON_IGNORE_CLEAR "edit-clear"
#endif
#if !HAVE_GTK3
#define ICON_IGNORE_NEW GTK_STOCK_NEW
#define ICON_IGNORE_DELETE GTK_STOCK_DELETE
#define ICON_IGNORE_CLEAR GTK_STOCK_CLEAR
#endif
enum enum
{ {
MASK_COLUMN, MASK_COLUMN,
@@ -360,7 +371,11 @@ ignore_gui_open ()
frame = gtk_frame_new (_("Ignore Stats:")); frame = gtk_frame_new (_("Ignore Stats:"));
gtk_widget_show (frame); gtk_widget_show (frame);
#if HAVE_GTK3
stat_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
#elif !HAVE_GTK3
stat_box = gtk_hbox_new (0, 2); stat_box = gtk_hbox_new (0, 2);
#endif
gtk_container_set_border_width (GTK_CONTAINER (stat_box), 6); gtk_container_set_border_width (GTK_CONTAINER (stat_box), 6);
gtk_container_add (GTK_CONTAINER (frame), stat_box); gtk_container_add (GTK_CONTAINER (frame), stat_box);
gtk_widget_show (stat_box); gtk_widget_show (stat_box);
@@ -373,17 +388,22 @@ ignore_gui_open ()
gtk_box_pack_start (GTK_BOX (vbox), frame, 0, 0, 5); gtk_box_pack_start (GTK_BOX (vbox), frame, 0, 0, 5);
#if HAVE_GTK3
box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
box = gtk_hbutton_box_new (); box = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_SPREAD);
#endif
gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER (box), 5); gtk_container_set_border_width (GTK_CONTAINER (box), 5);
gtk_widget_show (box); gtk_widget_show (box);
gtkutil_button (box, GTK_STOCK_NEW, 0, ignore_new_entry_clicked, 0, gtkutil_button (box, ICON_IGNORE_NEW, 0, ignore_new_entry_clicked, 0,
_("Add...")); _("Add..."));
gtkutil_button (box, GTK_STOCK_DELETE, 0, ignore_delete_entry_clicked, gtkutil_button (box, ICON_IGNORE_DELETE, 0, ignore_delete_entry_clicked,
0, _("Delete")); 0, _("Delete"));
gtkutil_button (box, GTK_STOCK_CLEAR, 0, ignore_clear_entry_clicked, gtkutil_button (box, ICON_IGNORE_CLEAR, 0, ignore_clear_entry_clicked,
0, _("Clear")); 0, _("Clear"));
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view))); store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));

View File

@@ -38,6 +38,14 @@
#include "../common/fe.h" #include "../common/fe.h"
#include "fe-gtk.h" #include "fe-gtk.h"
#include "chanlist.h" #include "chanlist.h"
#include "gtkutil.h"
#if HAVE_GTK3
#define ICON_JOIND_NETWORK "network-workgroup"
#endif
#if !HAVE_GTK3
#define ICON_JOIND_NETWORK GTK_STOCK_NETWORK
#endif
static void static void
@@ -124,7 +132,6 @@ joind_show_dialog (server *serv)
GtkWidget *hbox2; GtkWidget *hbox2;
GtkWidget *entry1; GtkWidget *entry1;
GtkWidget *checkbutton1; GtkWidget *checkbutton1;
GtkWidget *dialog_action_area1;
GtkWidget *okbutton1; GtkWidget *okbutton1;
char buf[256]; char buf[256];
char buf2[256]; char buf2[256];
@@ -141,20 +148,26 @@ joind_show_dialog (server *serv)
dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (dialog1)); dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (dialog1));
gtk_widget_show (dialog_vbox1); gtk_widget_show (dialog_vbox1);
vbox1 = gtk_vbox_new (FALSE, 0); vbox1 = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
gtk_widget_show (vbox1); gtk_widget_show (vbox1);
gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0);
hbox1 = gtk_hbox_new (FALSE, 0); hbox1 = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
gtk_widget_show (hbox1); gtk_widget_show (hbox1);
gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
image1 = gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_LARGE_TOOLBAR); image1 = gtkutil_image_new_from_stock (ICON_JOIND_NETWORK, GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_widget_show (image1); gtk_widget_show (image1);
gtk_box_pack_start (GTK_BOX (hbox1), image1, FALSE, TRUE, 24); gtk_box_pack_start (GTK_BOX (hbox1), image1, FALSE, TRUE, 24);
#if HAVE_GTK3
gtk_widget_set_halign (image1, GTK_ALIGN_CENTER);
gtk_widget_set_valign (image1, GTK_ALIGN_START);
gtk_widget_set_margin_top (image1, 2);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (image1), 0.5f, 0.06f); gtk_misc_set_alignment (GTK_MISC (image1), 0.5f, 0.06f);
#endif
vbox2 = gtk_vbox_new (FALSE, 10); vbox2 = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6); gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6);
gtk_widget_show (vbox2); gtk_widget_show (vbox2);
gtk_box_pack_start (GTK_BOX (hbox1), vbox2, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox1), vbox2, TRUE, TRUE, 0);
@@ -166,25 +179,40 @@ joind_show_dialog (server *serv)
gtk_widget_show (label); gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
#if HAVE_GTK3
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#endif
label = gtk_label_new (_("In the server list window, no channel (chat room) has been entered to be automatically joined for this network.")); label = gtk_label_new (_("In the server list window, no channel (chat room) has been entered to be automatically joined for this network."));
gtk_widget_show (label); gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
#if HAVE_GTK3
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#endif
label = gtk_label_new (_("What would you like to do next?")); label = gtk_label_new (_("What would you like to do next?"));
gtk_widget_show (label); gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
#if HAVE_GTK3
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#endif
serv->gui->joind_radio1 = radiobutton1 = gtk_radio_button_new_with_mnemonic (NULL, _("_Nothing, I'll join a channel later.")); serv->gui->joind_radio1 = radiobutton1 = gtk_radio_button_new_with_mnemonic (NULL, _("_Nothing, I'll join a channel later."));
gtk_widget_show (radiobutton1); gtk_widget_show (radiobutton1);
gtk_box_pack_start (GTK_BOX (vbox2), radiobutton1, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), radiobutton1, FALSE, FALSE, 0);
radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton1)); radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton1));
hbox2 = gtk_hbox_new (FALSE, 0); hbox2 = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
gtk_widget_show (hbox2); gtk_widget_show (hbox2);
gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
@@ -205,7 +233,12 @@ joind_show_dialog (server *serv)
gtk_widget_show (label); gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
#if HAVE_GTK3
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#endif
radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("O_pen the channel list.")); radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("O_pen the channel list."));
gtk_widget_show (radiobutton3); gtk_widget_show (radiobutton3);
@@ -218,7 +251,12 @@ joind_show_dialog (server *serv)
gtk_widget_show (label); gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
#if HAVE_GTK3
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#endif
serv->gui->joind_check = checkbutton1 = gtk_check_button_new_with_mnemonic (_("_Always show this dialog after connecting.")); serv->gui->joind_check = checkbutton1 = gtk_check_button_new_with_mnemonic (_("_Always show this dialog after connecting."));
if (prefs.hex_gui_join_dialog) if (prefs.hex_gui_join_dialog)
@@ -226,13 +264,20 @@ joind_show_dialog (server *serv)
gtk_widget_show (checkbutton1); gtk_widget_show (checkbutton1);
gtk_box_pack_start (GTK_BOX (vbox1), checkbutton1, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox1), checkbutton1, FALSE, FALSE, 0);
dialog_action_area1 = gtk_dialog_get_action_area (GTK_DIALOG (dialog1)); okbutton1 = gtkutil_button_new_from_stock ("gtk-ok", _("_OK"));
gtk_widget_show (dialog_action_area1);
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
okbutton1 = gtk_button_new_from_stock ("gtk-ok");
gtk_widget_show (okbutton1); gtk_widget_show (okbutton1);
gtk_box_pack_end (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog1))), okbutton1, FALSE, TRUE, 0); #if HAVE_GTK3
gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), okbutton1, GTK_RESPONSE_OK);
#elif !HAVE_GTK3
{
GtkWidget *dialog_action_area1;
dialog_action_area1 = gtk_dialog_get_action_area (GTK_DIALOG (dialog1));
gtk_widget_show (dialog_action_area1);
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
gtk_box_pack_end (GTK_BOX (dialog_action_area1), okbutton1, FALSE, TRUE, 0);
}
#endif
gtk_widget_set_can_default (okbutton1, TRUE); gtk_widget_set_can_default (okbutton1, TRUE);
g_signal_connect (G_OBJECT (dialog1), "destroy", g_signal_connect (G_OBJECT (dialog1), "destroy",

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@
#ifndef ZOITECHAT_MAINGUI_H #ifndef ZOITECHAT_MAINGUI_H
#define ZOITECHAT_MAINGUI_H #define ZOITECHAT_MAINGUI_H
extern GtkStyle *input_style; extern InputStyle *input_style;
extern GtkWidget *parent_window; extern GtkWidget *parent_window;
void mg_changui_new (session *sess, restore_gui *res, int tab, int focus); void mg_changui_new (session *sess, restore_gui *res, int tab, int focus);

View File

@@ -267,6 +267,12 @@ menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags,
{ {
GtkWidget *img, *item; GtkWidget *img, *item;
char *path; char *path;
#if HAVE_GTK3
const char *icon_name = NULL;
GtkWidget *box;
GtkWidget *image = NULL;
GtkWidget *label_widget;
#endif
if (!label) if (!label)
item = gtk_menu_item_new (); item = gtk_menu_item_new ();
@@ -277,7 +283,6 @@ menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags,
/*if (flags & XCMENU_MARKUP) /*if (flags & XCMENU_MARKUP)
item = gtk_image_menu_item_new_with_markup (label); item = gtk_image_menu_item_new_with_markup (label);
else*/ else*/
item = gtk_image_menu_item_new_with_mnemonic (label);
img = NULL; img = NULL;
if (access (icon, R_OK) == 0) /* try fullpath */ if (access (icon, R_OK) == 0) /* try fullpath */
img = gtk_image_new_from_file (icon); img = gtk_image_new_from_file (icon);
@@ -288,12 +293,36 @@ menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags,
if (access (path, R_OK) == 0) if (access (path, R_OK) == 0)
img = gtk_image_new_from_file (path); img = gtk_image_new_from_file (path);
else else
{
#if HAVE_GTK3
icon_name = gtkutil_icon_name_from_stock (icon);
if (!icon_name)
icon_name = icon;
#endif
#if !HAVE_GTK3
img = gtk_image_new_from_stock (icon, GTK_ICON_SIZE_MENU); img = gtk_image_new_from_stock (icon, GTK_ICON_SIZE_MENU);
#endif
}
g_free (path); g_free (path);
} }
#if HAVE_GTK3
item = gtk_menu_item_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
if (icon_name)
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
else if (img)
image = img;
label_widget = gtk_label_new_with_mnemonic (label);
if (image)
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), label_widget, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (item), box);
#else
item = gtk_image_menu_item_new_with_mnemonic (label);
if (img) if (img)
gtk_image_menu_item_set_image ((GtkImageMenuItem *)item, img); gtk_image_menu_item_set_image ((GtkImageMenuItem *)item, img);
#endif
} }
else else
{ {
@@ -301,9 +330,20 @@ menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags,
{ {
item = gtk_menu_item_new_with_label (""); item = gtk_menu_item_new_with_label ("");
if (flags & XCMENU_MNEMONIC) if (flags & XCMENU_MNEMONIC)
{
#if HAVE_GTK3
gtk_label_set_markup_with_mnemonic (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), label);
#else
gtk_label_set_markup_with_mnemonic (GTK_LABEL (GTK_BIN (item)->child), label); gtk_label_set_markup_with_mnemonic (GTK_LABEL (GTK_BIN (item)->child), label);
else #endif
} else
{
#if HAVE_GTK3
gtk_label_set_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), label);
#else
gtk_label_set_markup (GTK_LABEL (GTK_BIN (item)->child), label); gtk_label_set_markup (GTK_LABEL (GTK_BIN (item)->child), label);
#endif
}
} else } else
{ {
if (flags & XCMENU_MNEMONIC) if (flags & XCMENU_MNEMONIC)
@@ -352,7 +392,11 @@ menu_quick_sub (char *name, GtkWidget *menu, GtkWidget **sub_item_ret, int flags
if (flags & XCMENU_MARKUP) if (flags & XCMENU_MARKUP)
{ {
sub_item = gtk_menu_item_new_with_label (""); sub_item = gtk_menu_item_new_with_label ("");
#if HAVE_GTK3
gtk_label_set_markup (GTK_LABEL (gtk_bin_get_child (GTK_BIN (sub_item))), name);
#else
gtk_label_set_markup (GTK_LABEL (GTK_BIN (sub_item)->child), name); gtk_label_set_markup (GTK_LABEL (GTK_BIN (sub_item)->child), name);
#endif
} }
else else
{ {
@@ -392,7 +436,11 @@ toggle_cb (GtkWidget *item, char *pref_name)
{ {
char buf[256]; char buf[256];
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
#else
if (GTK_CHECK_MENU_ITEM (item)->active) if (GTK_CHECK_MENU_ITEM (item)->active)
#endif
g_snprintf (buf, sizeof (buf), "set %s 1", pref_name); g_snprintf (buf, sizeof (buf), "set %s 1", pref_name);
else else
g_snprintf (buf, sizeof (buf), "set %s 0", pref_name); g_snprintf (buf, sizeof (buf), "set %s 0", pref_name);
@@ -573,8 +621,26 @@ menu_popup (GtkWidget *menu, GdkEventButton *event, gpointer objtounref)
g_object_unref (menu); g_object_unref (menu);
g_signal_connect (G_OBJECT (menu), "selection-done", g_signal_connect (G_OBJECT (menu), "selection-done",
G_CALLBACK (menu_destroy), objtounref); G_CALLBACK (menu_destroy), objtounref);
#if HAVE_GTK3
if (event)
{
gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *)event);
}
else if (parent_window)
{
gtk_menu_popup_at_widget (GTK_MENU (menu), GTK_WIDGET (parent_window),
GDK_GRAVITY_SOUTH_WEST,
GDK_GRAVITY_NORTH_WEST,
NULL);
}
else
{
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
}
#else
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
0, event ? event->time : 0); 0, event ? event->time : 0);
#endif
} }
static void static void
@@ -695,6 +761,9 @@ void
fe_userlist_update (session *sess, struct User *user) fe_userlist_update (session *sess, struct User *user)
{ {
GList *items, *next; GList *items, *next;
#if HAVE_GTK3
GList *iter;
#endif
if (!nick_submenu || !str_copy) if (!nick_submenu || !str_copy)
return; return;
@@ -707,6 +776,17 @@ fe_userlist_update (session *sess, struct User *user)
g_signal_handlers_disconnect_by_func (nick_submenu, menu_nickinfo_cb, sess); g_signal_handlers_disconnect_by_func (nick_submenu, menu_nickinfo_cb, sess);
/* destroy all the old items */ /* destroy all the old items */
#if HAVE_GTK3
items = gtk_container_get_children (GTK_CONTAINER (nick_submenu));
iter = items;
while (iter)
{
next = iter->next;
gtk_widget_destroy (iter->data);
iter = next;
}
g_list_free (items);
#else
items = ((GtkMenuShell *) nick_submenu)->children; items = ((GtkMenuShell *) nick_submenu)->children;
while (items) while (items)
{ {
@@ -714,6 +794,7 @@ fe_userlist_update (session *sess, struct User *user)
gtk_widget_destroy (items->data); gtk_widget_destroy (items->data);
items = next; items = next;
} }
#endif
/* and re-create them with new info */ /* and re-create them with new info */
menu_create_nickinfo_menu (user, nick_submenu); menu_create_nickinfo_menu (user, nick_submenu);
@@ -838,7 +919,18 @@ menu_setting_foreach (void (*callback) (session *), int id, guint state)
if (sess->gui->is_tab) if (sess->gui->is_tab)
maindone = TRUE; maindone = TRUE;
if (id != -1) if (id != -1)
GTK_CHECK_MENU_ITEM (sess->gui->menu_item[id])->active = state; {
GtkWidget *menu_item = sess->gui->menu_item[id];
if (menu_item != NULL)
{
#if HAVE_GTK3
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), state);
#else
GTK_CHECK_MENU_ITEM (menu_item)->active = state;
#endif
}
}
if (callback) if (callback)
callback (sess); callback (sess);
} }
@@ -1168,8 +1260,22 @@ usermenu_create (GtkWidget *menu)
static void static void
usermenu_destroy (GtkWidget * menu) usermenu_destroy (GtkWidget * menu)
{ {
GList *items = ((GtkMenuShell *) menu)->children; GList *items;
GList *next; GList *next;
#if HAVE_GTK3
GList *iter;
items = gtk_container_get_children (GTK_CONTAINER (menu));
iter = items;
while (iter)
{
next = iter->next;
gtk_widget_destroy (iter->data);
iter = next;
}
g_list_free (items);
#else
items = ((GtkMenuShell *) menu)->children;
while (items) while (items)
{ {
@@ -1177,6 +1283,7 @@ usermenu_destroy (GtkWidget * menu)
gtk_widget_destroy (items->data); gtk_widget_destroy (items->data);
items = next; items = next;
} }
#endif
} }
void void
@@ -1387,7 +1494,11 @@ menu_join_cb (GtkWidget *dialog, gint response, GtkEntry *entry)
switch (response) switch (response)
{ {
case GTK_RESPONSE_ACCEPT: case GTK_RESPONSE_ACCEPT:
#if HAVE_GTK3
menu_chan_join (NULL, (char *)gtk_entry_get_text (GTK_ENTRY (entry)));
#else
menu_chan_join (NULL, entry->text); menu_chan_join (NULL, entry->text);
#endif
break; break;
case GTK_RESPONSE_HELP: case GTK_RESPONSE_HELP:
@@ -1408,19 +1519,59 @@ static void
menu_join (GtkWidget * wid, gpointer none) menu_join (GtkWidget * wid, gpointer none)
{ {
GtkWidget *hbox, *dialog, *entry, *label; GtkWidget *hbox, *dialog, *entry, *label;
#if HAVE_GTK3
GtkWidget *content_area;
#endif
#if HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (_("Join Channel"),
GTK_WINDOW (parent_window), 0,
_("Retrieve channel list"), GTK_RESPONSE_HELP,
_("_Cancel"), GTK_RESPONSE_REJECT,
_("_OK"), GTK_RESPONSE_ACCEPT,
NULL);
{
GtkWidget *button;
button = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_HELP);
if (button)
gtk_button_set_image (GTK_BUTTON (button),
gtk_image_new_from_icon_name ("help-browser", GTK_ICON_SIZE_BUTTON));
button = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_REJECT);
if (button)
gtk_button_set_image (GTK_BUTTON (button),
gtk_image_new_from_icon_name ("dialog-cancel", GTK_ICON_SIZE_BUTTON));
button = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
if (button)
gtk_button_set_image (GTK_BUTTON (button),
gtk_image_new_from_icon_name ("dialog-ok", GTK_ICON_SIZE_BUTTON));
}
#endif
#if !HAVE_GTK3
dialog = gtk_dialog_new_with_buttons (_("Join Channel"), dialog = gtk_dialog_new_with_buttons (_("Join Channel"),
GTK_WINDOW (parent_window), 0, GTK_WINDOW (parent_window), 0,
_("Retrieve channel list"), GTK_RESPONSE_HELP, _("Retrieve channel list"), GTK_RESPONSE_HELP,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL); NULL);
#endif
#if HAVE_GTK3
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_box_set_homogeneous (GTK_BOX (content_area), TRUE);
#else
gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->vbox), TRUE); gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->vbox), TRUE);
#endif
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
hbox = gtk_hbox_new (TRUE, 0); hbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, TRUE, 0);
entry = gtk_entry_new (); entry = gtk_entry_new ();
#if HAVE_GTK3
gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE); /* avoid auto-selection */
#else
GTK_ENTRY (entry)->editable = 0; /* avoid auto-selection */ GTK_ENTRY (entry)->editable = 0; /* avoid auto-selection */
#endif
gtk_entry_set_text (GTK_ENTRY (entry), "#"); gtk_entry_set_text (GTK_ENTRY (entry), "#");
g_signal_connect (G_OBJECT (entry), "activate", g_signal_connect (G_OBJECT (entry), "activate",
G_CALLBACK (menu_join_entry_cb), dialog); G_CALLBACK (menu_join_entry_cb), dialog);
@@ -1432,7 +1583,11 @@ menu_join (GtkWidget * wid, gpointer none)
g_signal_connect (G_OBJECT (dialog), "response", g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (menu_join_cb), entry); G_CALLBACK (menu_join_cb), entry);
#if HAVE_GTK3
gtk_container_add (GTK_CONTAINER (content_area), hbox);
#else
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
#endif
gtk_widget_show_all (dialog); gtk_widget_show_all (dialog);
@@ -1655,7 +1810,11 @@ static void
menu_layout_cb (GtkWidget *item, gpointer none) menu_layout_cb (GtkWidget *item, gpointer none)
{ {
prefs.hex_gui_tab_layout = 2; prefs.hex_gui_tab_layout = 2;
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
#else
if (GTK_CHECK_MENU_ITEM (item)->active) if (GTK_CHECK_MENU_ITEM (item)->active)
#endif
prefs.hex_gui_tab_layout = 0; prefs.hex_gui_tab_layout = 0;
menu_change_layout (); menu_change_layout ();
@@ -1670,7 +1829,11 @@ menu_apply_metres_cb (session *sess)
static void static void
menu_metres_off (GtkWidget *item, gpointer none) menu_metres_off (GtkWidget *item, gpointer none)
{ {
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
#else
if (GTK_CHECK_MENU_ITEM (item)->active) if (GTK_CHECK_MENU_ITEM (item)->active)
#endif
{ {
prefs.hex_gui_lagometer = 0; prefs.hex_gui_lagometer = 0;
prefs.hex_gui_throttlemeter = 0; prefs.hex_gui_throttlemeter = 0;
@@ -1682,7 +1845,11 @@ menu_metres_off (GtkWidget *item, gpointer none)
static void static void
menu_metres_text (GtkWidget *item, gpointer none) menu_metres_text (GtkWidget *item, gpointer none)
{ {
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
#else
if (GTK_CHECK_MENU_ITEM (item)->active) if (GTK_CHECK_MENU_ITEM (item)->active)
#endif
{ {
prefs.hex_gui_lagometer = 2; prefs.hex_gui_lagometer = 2;
prefs.hex_gui_throttlemeter = 2; prefs.hex_gui_throttlemeter = 2;
@@ -1694,7 +1861,11 @@ menu_metres_text (GtkWidget *item, gpointer none)
static void static void
menu_metres_graph (GtkWidget *item, gpointer none) menu_metres_graph (GtkWidget *item, gpointer none)
{ {
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
#else
if (GTK_CHECK_MENU_ITEM (item)->active) if (GTK_CHECK_MENU_ITEM (item)->active)
#endif
{ {
prefs.hex_gui_lagometer = 1; prefs.hex_gui_lagometer = 1;
prefs.hex_gui_throttlemeter = 1; prefs.hex_gui_throttlemeter = 1;
@@ -1706,7 +1877,11 @@ menu_metres_graph (GtkWidget *item, gpointer none)
static void static void
menu_metres_both (GtkWidget *item, gpointer none) menu_metres_both (GtkWidget *item, gpointer none)
{ {
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
#else
if (GTK_CHECK_MENU_ITEM (item)->active) if (GTK_CHECK_MENU_ITEM (item)->active)
#endif
{ {
prefs.hex_gui_lagometer = 3; prefs.hex_gui_lagometer = 3;
prefs.hex_gui_throttlemeter = 3; prefs.hex_gui_throttlemeter = 3;
@@ -1757,7 +1932,11 @@ menu_about (GtkWidget *wid, gpointer sess)
gtk_about_dialog_set_program_name (dialog, _(DISPLAY_NAME)); gtk_about_dialog_set_program_name (dialog, _(DISPLAY_NAME));
gtk_about_dialog_set_version (dialog, PACKAGE_VERSION); gtk_about_dialog_set_version (dialog, PACKAGE_VERSION);
gtk_about_dialog_set_license (dialog, license); /* gtk3 can use GTK_LICENSE_GPL_2_0 */ #if HAVE_GTK3
gtk_about_dialog_set_license_type (GTK_ABOUT_DIALOG (dialog), GTK_LICENSE_GPL_2_0);
#else
gtk_about_dialog_set_license (dialog, license);
#endif
gtk_about_dialog_set_website (dialog, "http://zoitechat.zoite.net"); gtk_about_dialog_set_website (dialog, "http://zoitechat.zoite.net");
gtk_about_dialog_set_website_label (dialog, "Website"); gtk_about_dialog_set_website_label (dialog, "Website");
gtk_about_dialog_set_logo (dialog, pix_zoitechat); gtk_about_dialog_set_logo (dialog, pix_zoitechat);
@@ -1771,12 +1950,49 @@ menu_about (GtkWidget *wid, gpointer sess)
gtk_widget_show_all (GTK_WIDGET(dialog)); gtk_widget_show_all (GTK_WIDGET(dialog));
} }
#if HAVE_GTK3
#define ICON_NEW "document-new"
#define ICON_LOAD_PLUGIN "document-open"
#define ICON_DETACH "edit-redo"
#define ICON_CLOSE "window-close"
#define ICON_QUIT "application-exit"
#define ICON_DISCONNECT "network-disconnect"
#define ICON_CONNECT "network-connect"
#define ICON_JOIN "go-jump"
#define ICON_CHANLIST "view-list"
#define ICON_PREFERENCES "preferences-system"
#define ICON_CLEAR "edit-clear"
#define ICON_SAVE "document-save"
#define ICON_SEARCH "edit-find"
#define ICON_FIND "edit-find"
#define ICON_HELP "help-contents"
#define ICON_ABOUT "help-about"
#endif
#if !HAVE_GTK3
#define ICON_NEW GTK_STOCK_NEW
#define ICON_LOAD_PLUGIN GTK_STOCK_REVERT_TO_SAVED
#define ICON_DETACH GTK_STOCK_REDO
#define ICON_CLOSE GTK_STOCK_CLOSE
#define ICON_QUIT GTK_STOCK_QUIT
#define ICON_DISCONNECT GTK_STOCK_DISCONNECT
#define ICON_CONNECT GTK_STOCK_CONNECT
#define ICON_JOIN GTK_STOCK_JUMP_TO
#define ICON_CHANLIST GTK_STOCK_INDEX
#define ICON_PREFERENCES GTK_STOCK_PREFERENCES
#define ICON_CLEAR GTK_STOCK_CLEAR
#define ICON_SAVE GTK_STOCK_SAVE
#define ICON_SEARCH GTK_STOCK_JUSTIFY_LEFT
#define ICON_FIND GTK_STOCK_FIND
#define ICON_HELP GTK_STOCK_HELP
#define ICON_ABOUT GTK_STOCK_ABOUT
#endif
static struct mymenu mymenu[] = { static struct mymenu mymenu[] = {
{N_("_ZoiteChat"), 0, 0, M_NEWMENU, MENU_ID_ZOITECHAT, 0, 1}, {N_("_ZoiteChat"), 0, 0, M_NEWMENU, MENU_ID_ZOITECHAT, 0, 1},
{N_("Network Li_st"), menu_open_server_list, (char *)&pix_book, M_MENUPIX, 0, 0, 1, GDK_KEY_s}, {N_("Network Li_st"), menu_open_server_list, (char *)&pix_book, M_MENUPIX, 0, 0, 1, GDK_KEY_s},
{0, 0, 0, M_SEP, 0, 0, 0}, {0, 0, 0, M_SEP, 0, 0, 0},
{N_("_New"), 0, GTK_STOCK_NEW, M_MENUSUB, 0, 0, 1}, {N_("_New"), 0, ICON_NEW, M_MENUSUB, 0, 0, 1},
{N_("Server Tab"), menu_newserver_tab, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_t}, {N_("Server Tab"), menu_newserver_tab, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_t},
{N_("Channel Tab"), menu_newchannel_tab, 0, M_MENUITEM, 0, 0, 1}, {N_("Channel Tab"), menu_newchannel_tab, 0, M_MENUITEM, 0, 0, 1},
{N_("Server Window"), menu_newserver_window, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_n}, {N_("Server Window"), menu_newserver_window, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_n},
@@ -1784,14 +2000,14 @@ static struct mymenu mymenu[] = {
{0, 0, 0, M_END, 0, 0, 0}, {0, 0, 0, M_END, 0, 0, 0},
{0, 0, 0, M_SEP, 0, 0, 0}, {0, 0, 0, M_SEP, 0, 0, 0},
{N_("_Load Plugin or Script" ELLIPSIS), menu_loadplugin, GTK_STOCK_REVERT_TO_SAVED, M_MENUSTOCK, 0, 0, 1}, {N_("_Load Plugin or Script" ELLIPSIS), menu_loadplugin, ICON_LOAD_PLUGIN, M_MENUSTOCK, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0}, /* 11 */ {0, 0, 0, M_SEP, 0, 0, 0}, /* 11 */
#define DETACH_OFFSET (12) #define DETACH_OFFSET (12)
{0, menu_detach, GTK_STOCK_REDO, M_MENUSTOCK, 0, 0, 1}, /* 12 */ {0, menu_detach, ICON_DETACH, M_MENUSTOCK, 0, 0, 1}, /* 12 */
#define CLOSE_OFFSET (13) #define CLOSE_OFFSET (13)
{0, menu_close, GTK_STOCK_CLOSE, M_MENUSTOCK, 0, 0, 1}, {0, menu_close, ICON_CLOSE, M_MENUSTOCK, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0}, {0, 0, 0, M_SEP, 0, 0, 0},
{N_("_Quit"), menu_quit, GTK_STOCK_QUIT, M_MENUSTOCK, 0, 0, 1, GDK_KEY_q}, /* 15 */ {N_("_Quit"), menu_quit, ICON_QUIT, M_MENUSTOCK, 0, 0, 1, GDK_KEY_q}, /* 15 */
{N_("_View"), 0, 0, M_NEWMENU, 0, 0, 1}, {N_("_View"), 0, 0, M_NEWMENU, 0, 0, 1},
#define MENUBAR_OFFSET (17) #define MENUBAR_OFFSET (17)
@@ -1817,10 +2033,10 @@ static struct mymenu mymenu[] = {
{N_ ("_Fullscreen"), menu_fullscreen_toggle, 0, M_MENUTOG, MENU_ID_FULLSCREEN, 0, 1, GDK_KEY_F11}, {N_ ("_Fullscreen"), menu_fullscreen_toggle, 0, M_MENUTOG, MENU_ID_FULLSCREEN, 0, 1, GDK_KEY_F11},
{N_("_Server"), 0, 0, M_NEWMENU, 0, 0, 1}, {N_("_Server"), 0, 0, M_NEWMENU, 0, 0, 1},
{N_("_Disconnect"), menu_disconnect, GTK_STOCK_DISCONNECT, M_MENUSTOCK, MENU_ID_DISCONNECT, 0, 1}, {N_("_Disconnect"), menu_disconnect, ICON_DISCONNECT, M_MENUSTOCK, MENU_ID_DISCONNECT, 0, 1},
{N_("_Reconnect"), menu_reconnect, GTK_STOCK_CONNECT, M_MENUSTOCK, MENU_ID_RECONNECT, 0, 1}, {N_("_Reconnect"), menu_reconnect, ICON_CONNECT, M_MENUSTOCK, MENU_ID_RECONNECT, 0, 1},
{N_("_Join a Channel" ELLIPSIS), menu_join, GTK_STOCK_JUMP_TO, M_MENUSTOCK, MENU_ID_JOIN, 0, 1}, {N_("_Join a Channel" ELLIPSIS), menu_join, ICON_JOIN, M_MENUSTOCK, MENU_ID_JOIN, 0, 1},
{N_("Channel _List"), menu_chanlist, GTK_STOCK_INDEX, M_MENUITEM, 0, 0, 1}, {N_("Channel _List"), menu_chanlist, ICON_CHANLIST, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0}, {0, 0, 0, M_SEP, 0, 0, 0},
#define AWAY_OFFSET (41) #define AWAY_OFFSET (41)
{N_("Marked _Away"), menu_away, 0, M_MENUTOG, MENU_ID_AWAY, 0, 1, GDK_KEY_a}, {N_("Marked _Away"), menu_away, 0, M_MENUTOG, MENU_ID_AWAY, 0, 1, GDK_KEY_a},
@@ -1828,7 +2044,7 @@ static struct mymenu mymenu[] = {
{N_("_Usermenu"), 0, 0, M_NEWMENU, MENU_ID_USERMENU, 0, 1}, /* 40 */ {N_("_Usermenu"), 0, 0, M_NEWMENU, MENU_ID_USERMENU, 0, 1}, /* 40 */
{N_("S_ettings"), 0, 0, M_NEWMENU, 0, 0, 1}, {N_("S_ettings"), 0, 0, M_NEWMENU, 0, 0, 1},
{N_("_Preferences"), menu_settings, GTK_STOCK_PREFERENCES, M_MENUSTOCK, 0, 0, 1}, {N_("_Preferences"), menu_settings, ICON_PREFERENCES, M_MENUSTOCK, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0}, {0, 0, 0, M_SEP, 0, 0, 0},
{N_("Auto Replace"), menu_rpopup, 0, M_MENUITEM, 0, 0, 1}, {N_("Auto Replace"), menu_rpopup, 0, M_MENUITEM, 0, 0, 1},
{N_("CTCP Replies"), menu_ctcpguiopen, 0, M_MENUITEM, 0, 0, 1}, {N_("CTCP Replies"), menu_ctcpguiopen, 0, M_MENUITEM, 0, 0, 1},
@@ -1854,18 +2070,18 @@ static struct mymenu mymenu[] = {
{N_("Reset Marker Line"), menu_resetmarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_m}, {N_("Reset Marker Line"), menu_resetmarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_m},
{N_("Move to Marker Line"), menu_movetomarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_M}, {N_("Move to Marker Line"), menu_movetomarker, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_M},
{N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_C}, {N_("_Copy Selection"), menu_copy_selection, 0, M_MENUITEM, 0, 0, 1, GDK_KEY_C},
{N_("C_lear Text"), menu_flushbuffer, GTK_STOCK_CLEAR, M_MENUSTOCK, 0, 0, 1}, {N_("C_lear Text"), menu_flushbuffer, ICON_CLEAR, M_MENUSTOCK, 0, 0, 1},
{N_("Save Text" ELLIPSIS), menu_savebuffer, GTK_STOCK_SAVE, M_MENUSTOCK, 0, 0, 1}, {N_("Save Text" ELLIPSIS), menu_savebuffer, ICON_SAVE, M_MENUSTOCK, 0, 0, 1},
#define SEARCH_OFFSET (70) #define SEARCH_OFFSET (70)
{N_("Search"), 0, GTK_STOCK_JUSTIFY_LEFT, M_MENUSUB, 0, 0, 1}, {N_("Search"), 0, ICON_SEARCH, M_MENUSUB, 0, 0, 1},
{N_("Search Text" ELLIPSIS), menu_search, GTK_STOCK_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_f}, {N_("Search Text" ELLIPSIS), menu_search, ICON_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_f},
{N_("Search Next" ), menu_search_next, GTK_STOCK_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_g}, {N_("Search Next" ), menu_search_next, ICON_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_g},
{N_("Search Previous" ), menu_search_prev, GTK_STOCK_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_G}, {N_("Search Previous" ), menu_search_prev, ICON_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_G},
{0, 0, 0, M_END, 0, 0, 0}, {0, 0, 0, M_END, 0, 0, 0},
{N_("_Help"), 0, 0, M_NEWMENU, 0, 0, 1}, /* 74 */ {N_("_Help"), 0, 0, M_NEWMENU, 0, 0, 1}, /* 74 */
{N_("_Contents"), menu_docs, GTK_STOCK_HELP, M_MENUSTOCK, 0, 0, 1, GDK_KEY_F1}, {N_("_Contents"), menu_docs, ICON_HELP, M_MENUSTOCK, 0, 0, 1, GDK_KEY_F1},
{N_("_About"), menu_about, GTK_STOCK_ABOUT, M_MENUSTOCK, 0, 0, 1}, {N_("_About"), menu_about, ICON_ABOUT, M_MENUSTOCK, 0, 0, 1},
{0, 0, 0, M_END, 0, 0, 0}, {0, 0, 0, M_END, 0, 0, 0},
}; };
@@ -1893,15 +2109,56 @@ menu_set_fullscreen (session_gui *gui, int full)
GtkWidget * GtkWidget *
create_icon_menu (char *labeltext, void *stock_name, int is_stock) create_icon_menu (char *labeltext, void *stock_name, int is_stock)
{ {
GtkWidget *item, *img; GtkWidget *item;
#if HAVE_GTK3
GtkWidget *box;
GtkWidget *label_widget;
GtkWidget *image = NULL;
const char *icon_name;
#endif
#if !HAVE_GTK3
GtkWidget *img;
#endif
if (is_stock) if (is_stock)
{
#if HAVE_GTK3
icon_name = gtkutil_icon_name_from_stock (stock_name);
if (!icon_name)
icon_name = stock_name;
if (icon_name)
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
#endif
#if !HAVE_GTK3
img = gtk_image_new_from_stock (stock_name, GTK_ICON_SIZE_MENU); img = gtk_image_new_from_stock (stock_name, GTK_ICON_SIZE_MENU);
#endif
}
else else
{
#if HAVE_GTK3
image = gtk_image_new_from_pixbuf (*((GdkPixbuf **)stock_name));
#endif
#if !HAVE_GTK3
img = gtk_image_new_from_pixbuf (*((GdkPixbuf **)stock_name)); img = gtk_image_new_from_pixbuf (*((GdkPixbuf **)stock_name));
#endif
}
#if HAVE_GTK3
item = gtk_menu_item_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
label_widget = gtk_label_new_with_mnemonic (labeltext);
if (image)
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), label_widget, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (item), box);
if (image)
gtk_widget_show (image);
gtk_widget_show (label_widget);
gtk_widget_show (box);
#else
item = gtk_image_menu_item_new_with_mnemonic (labeltext); item = gtk_image_menu_item_new_with_mnemonic (labeltext);
gtk_image_menu_item_set_image ((GtkImageMenuItem *)item, img); gtk_image_menu_item_set_image ((GtkImageMenuItem *)item, img);
gtk_widget_show (img); gtk_widget_show (img);
#endif
return item; return item;
} }
@@ -1920,30 +2177,71 @@ menu_canacaccel (GtkWidget *widget, guint signal_id, gpointer user_data)
static GtkMenuItem * static GtkMenuItem *
menu_find_item (GtkWidget *menu, char *name) menu_find_item (GtkWidget *menu, char *name)
{ {
GList *items = ((GtkMenuShell *) menu)->children; GList *items;
#if HAVE_GTK3
GList *items_head;
#endif
GtkMenuItem *item; GtkMenuItem *item;
GtkWidget *child; GtkWidget *child;
const char *labeltext; const char *labeltext;
GtkMenuItem *found = NULL;
#if HAVE_GTK3
items_head = gtk_container_get_children (GTK_CONTAINER (menu));
items = items_head;
#else
items = ((GtkMenuShell *) menu)->children;
#endif
while (items) while (items)
{ {
item = items->data; item = items->data;
#if HAVE_GTK3
child = gtk_bin_get_child (GTK_BIN (item));
#else
child = GTK_BIN (item)->child; child = GTK_BIN (item)->child;
#endif
if (child) /* separators arn't labels, skip them */ if (child) /* separators arn't labels, skip them */
{ {
labeltext = g_object_get_data (G_OBJECT (item), "name"); labeltext = g_object_get_data (G_OBJECT (item), "name");
if (!labeltext) if (!labeltext)
labeltext = gtk_label_get_text (GTK_LABEL (child)); {
if (GTK_IS_LABEL (child))
labeltext = gtk_label_get_text (GTK_LABEL (child));
#ifdef HAVE_GTK3
else if (GTK_IS_CONTAINER (child))
{
GList *kids, *l;
kids = gtk_container_get_children (GTK_CONTAINER (child));
for (l = kids; l; l = l->next)
{
if (GTK_IS_LABEL (l->data))
{
labeltext = gtk_label_get_text (GTK_LABEL (l->data));
break;
}
}
g_list_free (kids);
}
#endif
}
if (!menu_streq (labeltext, name, 1)) if (!menu_streq (labeltext, name, 1))
return item; {
found = item;
break;
}
} else if (name == NULL) } else if (name == NULL)
{ {
return item; found = item;
break;
} }
items = items->next; items = items->next;
} }
#if HAVE_GTK3
g_list_free (items_head);
#endif
return NULL; return found;
} }
static GtkWidget * static GtkWidget *
@@ -2025,7 +2323,11 @@ menu_update_cb (GtkWidget *menu, menu_entry *me, char *target)
gtk_widget_set_sensitive (item, me->enable); gtk_widget_set_sensitive (item, me->enable);
/* must do it without triggering the callback */ /* must do it without triggering the callback */
if (GTK_IS_CHECK_MENU_ITEM (item)) if (GTK_IS_CHECK_MENU_ITEM (item))
#if HAVE_GTK3
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), me->state);
#else
GTK_CHECK_MENU_ITEM (item)->active = me->state; GTK_CHECK_MENU_ITEM (item)->active = me->state;
#endif
} }
} }
@@ -2034,7 +2336,11 @@ static void
menu_radio_cb (GtkCheckMenuItem *item, menu_entry *me) menu_radio_cb (GtkCheckMenuItem *item, menu_entry *me)
{ {
me->state = 0; me->state = 0;
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (item))
#else
if (item->active) if (item->active)
#endif
me->state = 1; me->state = 1;
/* update the state, incase this was changed via right-click. */ /* update the state, incase this was changed via right-click. */
@@ -2050,7 +2356,11 @@ static void
menu_toggle_cb (GtkCheckMenuItem *item, menu_entry *me) menu_toggle_cb (GtkCheckMenuItem *item, menu_entry *me)
{ {
me->state = 0; me->state = 0;
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (item))
#else
if (item->active) if (item->active)
#endif
me->state = 1; me->state = 1;
/* update the state, incase this was changed via right-click. */ /* update the state, incase this was changed via right-click. */
@@ -2092,7 +2402,17 @@ menu_reorder (GtkMenu *menu, GtkWidget *item, int pos)
return; return;
if (pos < 0) /* position offset from end/bottom */ if (pos < 0) /* position offset from end/bottom */
#if HAVE_GTK3
{
GList *children = gtk_container_get_children (GTK_CONTAINER (menu));
int length = g_list_length (children);
g_list_free (children);
gtk_menu_reorder_child (menu, item, (length + pos) - 1);
}
#else
gtk_menu_reorder_child (menu, item, (g_list_length (GTK_MENU_SHELL (menu)->children) + pos) - 1); gtk_menu_reorder_child (menu, item, (g_list_length (GTK_MENU_SHELL (menu)->children) + pos) - 1);
#endif
else else
gtk_menu_reorder_child (menu, item, pos); gtk_menu_reorder_child (menu, item, pos);
} }
@@ -2158,7 +2478,17 @@ menu_add_sub (GtkWidget *menu, menu_entry *me)
{ {
pos = me->pos; pos = me->pos;
if (pos < 0) /* position offset from end/bottom */ if (pos < 0) /* position offset from end/bottom */
#if HAVE_GTK3
{
GList *children = gtk_container_get_children (GTK_CONTAINER (menu));
int length = g_list_length (children);
g_list_free (children);
pos = length + pos;
}
#else
pos = g_list_length (GTK_MENU_SHELL (menu)->children) + pos; pos = g_list_length (GTK_MENU_SHELL (menu)->children) + pos;
#endif
menu_quick_sub (me->label, menu, &item, me->markup ? XCMENU_MARKUP|XCMENU_MNEMONIC : XCMENU_MNEMONIC, pos); menu_quick_sub (me->label, menu, &item, me->markup ? XCMENU_MARKUP|XCMENU_MNEMONIC : XCMENU_MNEMONIC, pos);
} }
return item; return item;
@@ -2436,7 +2766,11 @@ normalitem:
item = gtk_check_menu_item_new_with_mnemonic (_(mymenu[i].text)); item = gtk_check_menu_item_new_with_mnemonic (_(mymenu[i].text));
togitem: togitem:
/* must avoid callback for Radio buttons */ /* must avoid callback for Radio buttons */
#if HAVE_GTK3
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), mymenu[i].state);
#else
GTK_CHECK_MENU_ITEM (item)->active = mymenu[i].state; GTK_CHECK_MENU_ITEM (item)->active = mymenu[i].state;
#endif
/*gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), /*gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
mymenu[i].state);*/ mymenu[i].state);*/
if (mymenu[i].key != 0) if (mymenu[i].key != 0)

View File

@@ -28,18 +28,50 @@ zoitechat_gtk_sources = [
'xtext.c' 'xtext.c'
] ]
gtk_dep = dependency('gtk+-2.0', version: '>= 2.24.0') zoitechat_gtk_cflags = []
zoitechat_gtk_deps = [ zoitechat_gtk_deps = [
zoitechat_common_dep, zoitechat_common_dep,
libgmodule_dep, # used by libsexy libgmodule_dep, # used by libsexy
gtk_dep
] ]
if gtk_dep.get_pkgconfig_variable('target') == 'x11' if get_option('gtk3')
zoitechat_gtk_deps += dependency('x11') gtk_dep = dependency('gtk+-3.0', version: '>= 3.22')
zoitechat_gtk_cflags += '-DHAVE_GTK3'
if host_machine.system() != 'windows'
appindicator_dep = dependency('ayatana-appindicator3-0.1', required: false)
if appindicator_dep.found()
zoitechat_gtk_deps += appindicator_dep
zoitechat_gtk_cflags += '-DHAVE_AYATANA_APPINDICATOR'
else
appindicator_dep = dependency('appindicator3-0.1', required: false)
if appindicator_dep.found()
zoitechat_gtk_deps += appindicator_dep
zoitechat_gtk_cflags += '-DHAVE_APPINDICATOR'
endif
endif
endif
else
gtk_dep = dependency('gtk+-2.0', version: '>= 2.24.0')
zoitechat_gtk_cflags += '-DHAVE_GTK2'
endif endif
zoitechat_gtk_cflags = [] zoitechat_gtk_deps += gtk_dep
if host_machine.system() != 'windows'
if get_option('gtk3')
gdk_x11_dep = dependency('gdk-x11-3.0', required: false)
if gdk_x11_dep.found()
zoitechat_gtk_deps += gdk_x11_dep
endif
endif
x11_dep = dependency('x11', required: false)
if x11_dep.found()
zoitechat_gtk_deps += x11_dep
endif
endif
zoitechat_gtk_ldflags = [] zoitechat_gtk_ldflags = []

View File

@@ -37,6 +37,19 @@
#include "palette.h" #include "palette.h"
#include "notifygui.h" #include "notifygui.h"
#if HAVE_GTK3
#define ICON_NOTIFY_NEW "document-new"
#define ICON_NOTIFY_DELETE "edit-delete"
#define LABEL_NOTIFY_CANCEL _("_Cancel")
#define LABEL_NOTIFY_OK _("_OK")
#endif
#if !HAVE_GTK3
#define ICON_NOTIFY_NEW GTK_STOCK_NEW
#define ICON_NOTIFY_DELETE GTK_STOCK_DELETE
#define LABEL_NOTIFY_CANCEL GTK_STOCK_CANCEL
#define LABEL_NOTIFY_OK GTK_STOCK_OK
#endif
/* model for the notify treeview */ /* model for the notify treeview */
enum enum
@@ -64,7 +77,7 @@ notify_closegui (void)
} }
/* Need this to be able to set the foreground colour property of a row /* Need this to be able to set the foreground colour property of a row
* from a GdkColor * in the model -Vince * from a PaletteColor * in the model -Vince
*/ */
static void static void
notify_treecell_property_mapper (GtkTreeViewColumn *col, GtkCellRenderer *cell, notify_treecell_property_mapper (GtkTreeViewColumn *col, GtkCellRenderer *cell,
@@ -72,17 +85,44 @@ notify_treecell_property_mapper (GtkTreeViewColumn *col, GtkCellRenderer *cell,
gpointer data) gpointer data)
{ {
gchar *text; gchar *text;
GdkColor *colour; PaletteColor *colour;
int model_column = GPOINTER_TO_INT (data); int model_column = GPOINTER_TO_INT (data);
gtk_tree_model_get (GTK_TREE_MODEL (model), iter, gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
COLOUR_COLUMN, &colour, COLOUR_COLUMN, &colour,
model_column, &text, -1); model_column, &text, -1);
g_object_set (G_OBJECT (cell), "text", text, NULL); #if HAVE_GTK3
g_object_set (G_OBJECT (cell), "foreground-gdk", colour, NULL); g_object_set (G_OBJECT (cell), "text", text,
PALETTE_FOREGROUND_PROPERTY, colour, NULL);
if (colour)
gdk_rgba_free (colour);
#else
g_object_set (G_OBJECT (cell), "text", text,
PALETTE_FOREGROUND_PROPERTY, colour, NULL);
if (colour)
gdk_color_free (colour);
#endif
g_free (text); g_free (text);
} }
static void
notify_store_color (GtkListStore *store, GtkTreeIter *iter, const PaletteColor *color)
{
#if HAVE_GTK3
if (color)
{
GdkRGBA rgba = *color;
gtk_list_store_set (store, iter, COLOUR_COLUMN, &rgba, -1);
}
else
{
gtk_list_store_set (store, iter, COLOUR_COLUMN, NULL, -1);
}
#else
gtk_list_store_set (store, iter, COLOUR_COLUMN, color, -1);
#endif
}
static void static void
notify_row_cb (GtkTreeSelection *sel, GtkTreeView *view) notify_row_cb (GtkTreeSelection *sel, GtkTreeView *view)
{ {
@@ -105,6 +145,7 @@ notify_treeview_new (GtkWidget *box)
{ {
GtkListStore *store; GtkListStore *store;
GtkWidget *view; GtkWidget *view;
GtkWidget *scroll;
GtkTreeViewColumn *col; GtkTreeViewColumn *col;
int col_id; int col_id;
@@ -113,7 +154,7 @@ notify_treeview_new (GtkWidget *box)
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_POINTER, /* can't specify colour! */ PALETTE_GDK_TYPE,
G_TYPE_POINTER G_TYPE_POINTER
); );
g_return_val_if_fail (store != NULL, NULL); g_return_val_if_fail (store != NULL, NULL);
@@ -124,6 +165,8 @@ notify_treeview_new (GtkWidget *box)
STATUS_COLUMN, _("Status"), STATUS_COLUMN, _("Status"),
SERVER_COLUMN, _("Network"), SERVER_COLUMN, _("Network"),
SEEN_COLUMN, _("Last Seen"), -1); SEEN_COLUMN, _("Last Seen"), -1);
scroll = gtk_widget_get_parent (view);
gtk_box_set_child_packing (GTK_BOX (box), scroll, TRUE, TRUE, 0, GTK_PACK_START);
gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE); gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE);
for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id)); for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id));
@@ -200,7 +243,8 @@ notify_gui_update (void)
if (!valid) /* create new tree row if required */ if (!valid) /* create new tree row if required */
gtk_list_store_append (store, &iter); gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, name, 1, status, gtk_list_store_set (store, &iter, 0, name, 1, status,
2, server, 3, seen, 4, &colors[4], 5, NULL, -1); 2, server, 3, seen, 5, NULL, -1);
notify_store_color (store, &iter, &colors[4]);
if (valid) if (valid)
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
@@ -225,7 +269,8 @@ notify_gui_update (void)
if (!valid) /* create new tree row if required */ if (!valid) /* create new tree row if required */
gtk_list_store_append (store, &iter); gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, name, 1, status, gtk_list_store_set (store, &iter, 0, name, 1, status,
2, server, 3, seen, 4, &colors[3], 5, servnot, -1); 2, server, 3, seen, 5, servnot, -1);
notify_store_color (store, &iter, &colors[3]);
if (valid) if (valid)
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
@@ -344,45 +389,50 @@ fe_notify_ask (char *nick, char *networks)
char buf[256]; char buf[256];
dialog = gtk_dialog_new_with_buttons (msg, NULL, 0, dialog = gtk_dialog_new_with_buttons (msg, NULL, 0,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, LABEL_NOTIFY_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, LABEL_NOTIFY_OK, GTK_RESPONSE_ACCEPT,
NULL); NULL);
if (parent_window) if (parent_window)
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
table = gtk_table_new (2, 3, FALSE); table = gtkutil_grid_new (2, 3, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 12); gtk_container_set_border_width (GTK_CONTAINER (table), 12);
#if HAVE_GTK3
gtk_grid_set_row_spacing (GTK_GRID (table), 3);
gtk_grid_set_column_spacing (GTK_GRID (table), 8);
#else
gtk_table_set_row_spacings (GTK_TABLE (table), 3); gtk_table_set_row_spacings (GTK_TABLE (table), 3);
gtk_table_set_col_spacings (GTK_TABLE (table), 8); gtk_table_set_col_spacings (GTK_TABLE (table), 8);
#endif
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), table); gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), table);
label = gtk_label_new (msg); label = gtk_label_new (msg);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1); gtkutil_grid_attach_defaults (table, label, 0, 1, 0, 1);
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry), nick); gtk_entry_set_text (GTK_ENTRY (entry), nick);
g_signal_connect (G_OBJECT (entry), "activate", g_signal_connect (G_OBJECT (entry), "activate",
G_CALLBACK (notifygui_add_enter), dialog); G_CALLBACK (notifygui_add_enter), dialog);
gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 0, 1); gtkutil_grid_attach_defaults (table, entry, 1, 2, 0, 1);
g_signal_connect (G_OBJECT (dialog), "response", g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (notifygui_add_cb), entry); G_CALLBACK (notifygui_add_cb), entry);
label = gtk_label_new (_("Notify on these networks:")); label = gtk_label_new (_("Notify on these networks:"));
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3); gtkutil_grid_attach_defaults (table, label, 0, 1, 2, 3);
wid = gtk_entry_new (); wid = gtk_entry_new ();
g_object_set_data (G_OBJECT (entry), "net", wid); g_object_set_data (G_OBJECT (entry), "net", wid);
g_signal_connect (G_OBJECT (wid), "activate", g_signal_connect (G_OBJECT (wid), "activate",
G_CALLBACK (notifygui_add_enter), dialog); G_CALLBACK (notifygui_add_enter), dialog);
gtk_entry_set_text (GTK_ENTRY (wid), networks ? networks : "ALL"); gtk_entry_set_text (GTK_ENTRY (wid), networks ? networks : "ALL");
gtk_table_attach_defaults (GTK_TABLE (table), wid, 1, 2, 2, 3); gtkutil_grid_attach_defaults (table, wid, 1, 2, 2, 3);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
g_snprintf (buf, sizeof (buf), "<i><span size=\"smaller\">%s</span></i>", _("Comma separated list of networks is accepted.")); g_snprintf (buf, sizeof (buf), "<i><span size=\"smaller\">%s</span></i>", _("Comma separated list of networks is accepted."));
gtk_label_set_markup (GTK_LABEL (label), buf); gtk_label_set_markup (GTK_LABEL (label), buf);
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 3, 4); gtkutil_grid_attach_defaults (table, label, 1, 2, 3, 4);
gtk_widget_show_all (dialog); gtk_widget_show_all (dialog);
} }
@@ -415,17 +465,22 @@ notify_opengui (void)
view = notify_treeview_new (vbox); view = notify_treeview_new (vbox);
g_object_set_data (G_OBJECT (notify_window), "view", view); g_object_set_data (G_OBJECT (notify_window), "view", view);
#if HAVE_GTK3
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
bbox = gtk_hbutton_box_new (); bbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (bbox), 5); gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 0); gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 0);
gtk_widget_show (bbox); gtk_widget_show (bbox);
gtkutil_button (bbox, GTK_STOCK_NEW, 0, notify_add_clicked, 0, gtkutil_button (bbox, ICON_NOTIFY_NEW, 0, notify_add_clicked, 0,
_("Add...")); _("Add..."));
notify_button_remove = notify_button_remove =
gtkutil_button (bbox, GTK_STOCK_DELETE, 0, notify_remove_clicked, 0, gtkutil_button (bbox, ICON_NOTIFY_DELETE, 0, notify_remove_clicked, 0,
_("Remove")); _("Remove"));
notify_button_opendialog = notify_button_opendialog =

View File

@@ -38,121 +38,167 @@
#include "../common/cfgfiles.h" #include "../common/cfgfiles.h"
#include "../common/typedef.h" #include "../common/typedef.h"
#if HAVE_GTK3
#define PALETTE_COLOR_INIT(r, g, b) { (r) / 65535.0, (g) / 65535.0, (b) / 65535.0, 1.0 }
#else
#define PALETTE_COLOR_INIT(r, g, b) { 0, (r), (g), (b) }
#endif
static void
palette_color_set_rgb16 (PaletteColor *color, guint16 red, guint16 green, guint16 blue)
{
#if HAVE_GTK3
char color_string[16];
GdkRGBA parsed = { 0 };
gboolean parsed_ok;
g_snprintf (color_string, sizeof (color_string), "#%04x%04x%04x",
red, green, blue);
parsed_ok = gdk_rgba_parse (&parsed, color_string);
if (!parsed_ok)
{
parsed.red = red / 65535.0;
parsed.green = green / 65535.0;
parsed.blue = blue / 65535.0;
parsed.alpha = 1.0;
}
*color = parsed;
#else
char color_string[16];
g_snprintf (color_string, sizeof (color_string), "#%04x%04x%04x", red, green, blue);
if (!gdk_color_parse (color_string, color))
{
color->red = red;
color->green = green;
color->blue = blue;
color->pixel = 0;
}
#endif
}
static XTextColor static XTextColor
palette_color_from_gdk (const GdkColor *color) palette_color_from_gdk (const PaletteColor *color)
{ {
XTextColor result; XTextColor result;
#if HAVE_GTK3
result.red = color->red;
result.green = color->green;
result.blue = color->blue;
result.alpha = color->alpha;
#else
result.red = color->red / 65535.0; result.red = color->red / 65535.0;
result.green = color->green / 65535.0; result.green = color->green / 65535.0;
result.blue = color->blue / 65535.0; result.blue = color->blue / 65535.0;
result.alpha = 1.0; result.alpha = 1.0;
#endif
return result; return result;
} }
GdkColor colors[] = { PaletteColor colors[] = {
/* colors for xtext */ /* colors for xtext */
{0, 0xd3d3, 0xd7d7, 0xcfcf}, /* 0 white */ PALETTE_COLOR_INIT (0xd3d3, 0xd7d7, 0xcfcf), /* 0 white */
{0, 0x2e2e, 0x3434, 0x3636}, /* 1 black */ PALETTE_COLOR_INIT (0x2e2e, 0x3434, 0x3636), /* 1 black */
{0, 0x3434, 0x6565, 0xa4a4}, /* 2 blue */ PALETTE_COLOR_INIT (0x3434, 0x6565, 0xa4a4), /* 2 blue */
{0, 0x4e4e, 0x9a9a, 0x0606}, /* 3 green */ PALETTE_COLOR_INIT (0x4e4e, 0x9a9a, 0x0606), /* 3 green */
{0, 0xcccc, 0x0000, 0x0000}, /* 4 red */ PALETTE_COLOR_INIT (0xcccc, 0x0000, 0x0000), /* 4 red */
{0, 0x8f8f, 0x3939, 0x0202}, /* 5 light red */ PALETTE_COLOR_INIT (0x8f8f, 0x3939, 0x0202), /* 5 light red */
{0, 0x5c5c, 0x3535, 0x6666}, /* 6 purple */ PALETTE_COLOR_INIT (0x5c5c, 0x3535, 0x6666), /* 6 purple */
{0, 0xcece, 0x5c5c, 0x0000}, /* 7 orange */ PALETTE_COLOR_INIT (0xcece, 0x5c5c, 0x0000), /* 7 orange */
{0, 0xc4c4, 0xa0a0, 0x0000}, /* 8 yellow */ PALETTE_COLOR_INIT (0xc4c4, 0xa0a0, 0x0000), /* 8 yellow */
{0, 0x7373, 0xd2d2, 0x1616}, /* 9 green */ PALETTE_COLOR_INIT (0x7373, 0xd2d2, 0x1616), /* 9 green */
{0, 0x1111, 0xa8a8, 0x7979}, /* 10 aqua */ PALETTE_COLOR_INIT (0x1111, 0xa8a8, 0x7979), /* 10 aqua */
{0, 0x5858, 0xa1a1, 0x9d9d}, /* 11 light aqua */ PALETTE_COLOR_INIT (0x5858, 0xa1a1, 0x9d9d), /* 11 light aqua */
{0, 0x5757, 0x7979, 0x9e9e}, /* 12 blue */ PALETTE_COLOR_INIT (0x5757, 0x7979, 0x9e9e), /* 12 blue */
{0, 0xa0d0, 0x42d4, 0x6562}, /* 13 light purple */ PALETTE_COLOR_INIT (0xa0d0, 0x42d4, 0x6562), /* 13 light purple */
{0, 0x5555, 0x5757, 0x5353}, /* 14 grey */ PALETTE_COLOR_INIT (0x5555, 0x5757, 0x5353), /* 14 grey */
{0, 0x8888, 0x8a8a, 0x8585}, /* 15 light grey */ PALETTE_COLOR_INIT (0x8888, 0x8a8a, 0x8585), /* 15 light grey */
{0, 0xd3d3, 0xd7d7, 0xcfcf}, /* 16 white */ PALETTE_COLOR_INIT (0xd3d3, 0xd7d7, 0xcfcf), /* 16 white */
{0, 0x2e2e, 0x3434, 0x3636}, /* 17 black */ PALETTE_COLOR_INIT (0x2e2e, 0x3434, 0x3636), /* 17 black */
{0, 0x3434, 0x6565, 0xa4a4}, /* 18 blue */ PALETTE_COLOR_INIT (0x3434, 0x6565, 0xa4a4), /* 18 blue */
{0, 0x4e4e, 0x9a9a, 0x0606}, /* 19 green */ PALETTE_COLOR_INIT (0x4e4e, 0x9a9a, 0x0606), /* 19 green */
{0, 0xcccc, 0x0000, 0x0000}, /* 20 red */ PALETTE_COLOR_INIT (0xcccc, 0x0000, 0x0000), /* 20 red */
{0, 0x8f8f, 0x3939, 0x0202}, /* 21 light red */ PALETTE_COLOR_INIT (0x8f8f, 0x3939, 0x0202), /* 21 light red */
{0, 0x5c5c, 0x3535, 0x6666}, /* 22 purple */ PALETTE_COLOR_INIT (0x5c5c, 0x3535, 0x6666), /* 22 purple */
{0, 0xcece, 0x5c5c, 0x0000}, /* 23 orange */ PALETTE_COLOR_INIT (0xcece, 0x5c5c, 0x0000), /* 23 orange */
{0, 0xc4c4, 0xa0a0, 0x0000}, /* 24 yellow */ PALETTE_COLOR_INIT (0xc4c4, 0xa0a0, 0x0000), /* 24 yellow */
{0, 0x7373, 0xd2d2, 0x1616}, /* 25 green */ PALETTE_COLOR_INIT (0x7373, 0xd2d2, 0x1616), /* 25 green */
{0, 0x1111, 0xa8a8, 0x7979}, /* 26 aqua */ PALETTE_COLOR_INIT (0x1111, 0xa8a8, 0x7979), /* 26 aqua */
{0, 0x5858, 0xa1a1, 0x9d9d}, /* 27 light aqua */ PALETTE_COLOR_INIT (0x5858, 0xa1a1, 0x9d9d), /* 27 light aqua */
{0, 0x5757, 0x7979, 0x9e9e}, /* 28 blue */ PALETTE_COLOR_INIT (0x5757, 0x7979, 0x9e9e), /* 28 blue */
{0, 0xa0d0, 0x42d4, 0x6562}, /* 29 light purple */ PALETTE_COLOR_INIT (0xa0d0, 0x42d4, 0x6562), /* 29 light purple */
{0, 0x5555, 0x5757, 0x5353}, /* 30 grey */ PALETTE_COLOR_INIT (0x5555, 0x5757, 0x5353), /* 30 grey */
{0, 0x8888, 0x8a8a, 0x8585}, /* 31 light grey */ PALETTE_COLOR_INIT (0x8888, 0x8a8a, 0x8585), /* 31 light grey */
{0, 0xd3d3, 0xd7d7, 0xcfcf}, /* 32 marktext Fore (white) */ PALETTE_COLOR_INIT (0xd3d3, 0xd7d7, 0xcfcf), /* 32 marktext Fore (white) */
{0, 0x2020, 0x4a4a, 0x8787}, /* 33 marktext Back (blue) */ PALETTE_COLOR_INIT (0x2020, 0x4a4a, 0x8787), /* 33 marktext Back (blue) */
{0, 0x2512, 0x29e8, 0x2b85}, /* 34 foreground (black) */ PALETTE_COLOR_INIT (0x2512, 0x29e8, 0x2b85), /* 34 foreground (black) */
{0, 0xfae0, 0xfae0, 0xf8c4}, /* 35 background (white) */ PALETTE_COLOR_INIT (0xfae0, 0xfae0, 0xf8c4), /* 35 background (white) */
{0, 0x8f8f, 0x3939, 0x0202}, /* 36 marker line (red) */ PALETTE_COLOR_INIT (0x8f8f, 0x3939, 0x0202), /* 36 marker line (red) */
/* colors for GUI */ /* colors for GUI */
{0, 0x3434, 0x6565, 0xa4a4}, /* 37 tab New Data (dark red) */ PALETTE_COLOR_INIT (0x3434, 0x6565, 0xa4a4), /* 37 tab New Data (dark red) */
{0, 0x4e4e, 0x9a9a, 0x0606}, /* 38 tab Nick Mentioned (blue) */ PALETTE_COLOR_INIT (0x4e4e, 0x9a9a, 0x0606), /* 38 tab Nick Mentioned (blue) */
{0, 0xcece, 0x5c5c, 0x0000}, /* 39 tab New Message (red) */ PALETTE_COLOR_INIT (0xcece, 0x5c5c, 0x0000), /* 39 tab New Message (red) */
{0, 0x8888, 0x8a8a, 0x8585}, /* 40 away user (grey) */ PALETTE_COLOR_INIT (0x8888, 0x8a8a, 0x8585), /* 40 away user (grey) */
{0, 0xa4a4, 0x0000, 0x0000}, /* 41 spell checker color (red) */ PALETTE_COLOR_INIT (0xa4a4, 0x0000, 0x0000), /* 41 spell checker color (red) */
}; };
/* User palette snapshot (what we write to colors.conf) */ /* User palette snapshot (what we write to colors.conf) */
static GdkColor user_colors[MAX_COL + 1]; static PaletteColor user_colors[MAX_COL + 1];
static gboolean user_colors_valid = FALSE; static gboolean user_colors_valid = FALSE;
/* Dark palette snapshot (saved separately so dark mode can have its own custom palette). */ /* Dark palette snapshot (saved separately so dark mode can have its own custom palette). */
static GdkColor dark_user_colors[MAX_COL + 1]; static PaletteColor dark_user_colors[MAX_COL + 1];
static gboolean dark_user_colors_valid = FALSE; static gboolean dark_user_colors_valid = FALSE;
/* ZoiteChat's curated dark palette (applies when prefs.hex_gui_dark_mode is enabled). */ /* ZoiteChat's curated dark palette (applies when prefs.hex_gui_dark_mode is enabled). */
static const GdkColor dark_colors[MAX_COL + 1] = { static const PaletteColor dark_colors[MAX_COL + 1] = {
/* mIRC colors 0-15 */ /* mIRC colors 0-15 */
{0, 0xe5e5, 0xe5e5, 0xe5e5}, /* 0 white */ PALETTE_COLOR_INIT (0xe5e5, 0xe5e5, 0xe5e5), /* 0 white */
{0, 0x3c3c, 0x3c3c, 0x3c3c}, /* 1 black (dark gray for contrast) */ PALETTE_COLOR_INIT (0x3c3c, 0x3c3c, 0x3c3c), /* 1 black (dark gray for contrast) */
{0, 0x5656, 0x9c9c, 0xd6d6}, /* 2 blue */ PALETTE_COLOR_INIT (0x5656, 0x9c9c, 0xd6d6), /* 2 blue */
{0, 0x0d0d, 0xbcbc, 0x7979}, /* 3 green */ PALETTE_COLOR_INIT (0x0d0d, 0xbcbc, 0x7979), /* 3 green */
{0, 0xf4f4, 0x4747, 0x4747}, /* 4 red */ PALETTE_COLOR_INIT (0xf4f4, 0x4747, 0x4747), /* 4 red */
{0, 0xcece, 0x9191, 0x7878}, /* 5 light red / brown */ PALETTE_COLOR_INIT (0xcece, 0x9191, 0x7878), /* 5 light red / brown */
{0, 0xc5c5, 0x8686, 0xc0c0}, /* 6 purple */ PALETTE_COLOR_INIT (0xc5c5, 0x8686, 0xc0c0), /* 6 purple */
{0, 0xd7d7, 0xbaba, 0x7d7d}, /* 7 orange */ PALETTE_COLOR_INIT (0xd7d7, 0xbaba, 0x7d7d), /* 7 orange */
{0, 0xdcdc, 0xdcdc, 0xaaaa}, /* 8 yellow */ PALETTE_COLOR_INIT (0xdcdc, 0xdcdc, 0xaaaa), /* 8 yellow */
{0, 0xb5b5, 0xcece, 0xa8a8}, /* 9 light green */ PALETTE_COLOR_INIT (0xb5b5, 0xcece, 0xa8a8), /* 9 light green */
{0, 0x4e4e, 0xc9c9, 0xb0b0}, /* 10 aqua */ PALETTE_COLOR_INIT (0x4e4e, 0xc9c9, 0xb0b0), /* 10 aqua */
{0, 0x9c9c, 0xdcdc, 0xfefe}, /* 11 light aqua */ PALETTE_COLOR_INIT (0x9c9c, 0xdcdc, 0xfefe), /* 11 light aqua */
{0, 0x3737, 0x9494, 0xffff}, /* 12 light blue */ PALETTE_COLOR_INIT (0x3737, 0x9494, 0xffff), /* 12 light blue */
{0, 0xd6d6, 0x7070, 0xd6d6}, /* 13 pink */ PALETTE_COLOR_INIT (0xd6d6, 0x7070, 0xd6d6), /* 13 pink */
{0, 0x8080, 0x8080, 0x8080}, /* 14 gray */ PALETTE_COLOR_INIT (0x8080, 0x8080, 0x8080), /* 14 gray */
{0, 0xc0c0, 0xc0c0, 0xc0c0}, /* 15 light gray */ PALETTE_COLOR_INIT (0xc0c0, 0xc0c0, 0xc0c0), /* 15 light gray */
/* mIRC colors 16-31 (repeat) */ /* mIRC colors 16-31 (repeat) */
{0, 0xe5e5, 0xe5e5, 0xe5e5}, {0, 0x3c3c, 0x3c3c, 0x3c3c}, PALETTE_COLOR_INIT (0xe5e5, 0xe5e5, 0xe5e5), PALETTE_COLOR_INIT (0x3c3c, 0x3c3c, 0x3c3c),
{0, 0x5656, 0x9c9c, 0xd6d6}, {0, 0x0d0d, 0xbcbc, 0x7979}, PALETTE_COLOR_INIT (0x5656, 0x9c9c, 0xd6d6), PALETTE_COLOR_INIT (0x0d0d, 0xbcbc, 0x7979),
{0, 0xf4f4, 0x4747, 0x4747}, {0, 0xcece, 0x9191, 0x7878}, PALETTE_COLOR_INIT (0xf4f4, 0x4747, 0x4747), PALETTE_COLOR_INIT (0xcece, 0x9191, 0x7878),
{0, 0xc5c5, 0x8686, 0xc0c0}, {0, 0xd7d7, 0xbaba, 0x7d7d}, PALETTE_COLOR_INIT (0xc5c5, 0x8686, 0xc0c0), PALETTE_COLOR_INIT (0xd7d7, 0xbaba, 0x7d7d),
{0, 0xdcdc, 0xdcdc, 0xaaaa}, {0, 0xb5b5, 0xcece, 0xa8a8}, PALETTE_COLOR_INIT (0xdcdc, 0xdcdc, 0xaaaa), PALETTE_COLOR_INIT (0xb5b5, 0xcece, 0xa8a8),
{0, 0x4e4e, 0xc9c9, 0xb0b0}, {0, 0x9c9c, 0xdcdc, 0xfefe}, PALETTE_COLOR_INIT (0x4e4e, 0xc9c9, 0xb0b0), PALETTE_COLOR_INIT (0x9c9c, 0xdcdc, 0xfefe),
{0, 0x3737, 0x9494, 0xffff}, {0, 0xd6d6, 0x7070, 0xd6d6}, PALETTE_COLOR_INIT (0x3737, 0x9494, 0xffff), PALETTE_COLOR_INIT (0xd6d6, 0x7070, 0xd6d6),
{0, 0x8080, 0x8080, 0x8080}, {0, 0xc0c0, 0xc0c0, 0xc0c0}, PALETTE_COLOR_INIT (0x8080, 0x8080, 0x8080), PALETTE_COLOR_INIT (0xc0c0, 0xc0c0, 0xc0c0),
/* selection colors */ /* selection colors */
{0, 0xffff, 0xffff, 0xffff}, /* 32 COL_MARK_FG */ PALETTE_COLOR_INIT (0xffff, 0xffff, 0xffff), /* 32 COL_MARK_FG */
{0, 0x2626, 0x4f4f, 0x7878}, /* 33 COL_MARK_BG */ PALETTE_COLOR_INIT (0x2626, 0x4f4f, 0x7878), /* 33 COL_MARK_BG */
/* foreground/background */ /* foreground/background */
{0, 0xd4d4, 0xd4d4, 0xd4d4}, /* 34 COL_FG */ PALETTE_COLOR_INIT (0xd4d4, 0xd4d4, 0xd4d4), /* 34 COL_FG */
{0, 0x1e1e, 0x1e1e, 0x1e1e}, /* 35 COL_BG */ PALETTE_COLOR_INIT (0x1e1e, 0x1e1e, 0x1e1e), /* 35 COL_BG */
/* interface colors */ /* interface colors */
{0, 0x4040, 0x4040, 0x4040}, /* 36 COL_MARKER (marker line) */ PALETTE_COLOR_INIT (0x4040, 0x4040, 0x4040), /* 36 COL_MARKER (marker line) */
{0, 0x3737, 0x9494, 0xffff}, /* 37 COL_NEW_DATA (tab: new data) */ PALETTE_COLOR_INIT (0x3737, 0x9494, 0xffff), /* 37 COL_NEW_DATA (tab: new data) */
{0, 0xd7d7, 0xbaba, 0x7d7d}, /* 38 COL_HILIGHT (tab: nick mentioned) */ PALETTE_COLOR_INIT (0xd7d7, 0xbaba, 0x7d7d), /* 38 COL_HILIGHT (tab: nick mentioned) */
{0, 0xf4f4, 0x4747, 0x4747}, /* 39 COL_NEW_MSG (tab: new message) */ PALETTE_COLOR_INIT (0xf4f4, 0x4747, 0x4747), /* 39 COL_NEW_MSG (tab: new message) */
{0, 0x8080, 0x8080, 0x8080}, /* 40 COL_AWAY (tab: away) */ PALETTE_COLOR_INIT (0x8080, 0x8080, 0x8080), /* 40 COL_AWAY (tab: away) */
{0, 0xf4f4, 0x4747, 0x4747}, /* 41 COL_SPELL (spellcheck underline) */ PALETTE_COLOR_INIT (0xf4f4, 0x4747, 0x4747), /* 41 COL_SPELL (spellcheck underline) */
}; };
void void
@@ -168,7 +214,7 @@ palette_get_xtext_colors (XTextColor *palette, size_t palette_len)
} }
void void
palette_user_set_color (int idx, const GdkColor *col) palette_user_set_color (int idx, const PaletteColor *col)
{ {
if (!col) if (!col)
return; return;
@@ -181,14 +227,18 @@ palette_user_set_color (int idx, const GdkColor *col)
user_colors_valid = TRUE; user_colors_valid = TRUE;
} }
#if HAVE_GTK3
user_colors[idx] = *col;
#else
user_colors[idx].red = col->red; user_colors[idx].red = col->red;
user_colors[idx].green = col->green; user_colors[idx].green = col->green;
user_colors[idx].blue = col->blue; user_colors[idx].blue = col->blue;
user_colors[idx].pixel = 0; user_colors[idx].pixel = 0;
#endif
} }
void void
palette_dark_set_color (int idx, const GdkColor *col) palette_dark_set_color (int idx, const PaletteColor *col)
{ {
if (!col) if (!col)
return; return;
@@ -202,26 +252,20 @@ palette_dark_set_color (int idx, const GdkColor *col)
dark_user_colors_valid = TRUE; dark_user_colors_valid = TRUE;
} }
#if HAVE_GTK3
dark_user_colors[idx] = *col;
#else
dark_user_colors[idx].red = col->red; dark_user_colors[idx].red = col->red;
dark_user_colors[idx].green = col->green; dark_user_colors[idx].green = col->green;
dark_user_colors[idx].blue = col->blue; dark_user_colors[idx].blue = col->blue;
dark_user_colors[idx].pixel = 0; dark_user_colors[idx].pixel = 0;
#endif
} }
void void
palette_alloc (GtkWidget * widget) palette_alloc (GtkWidget * widget)
{ {
int i; (void) widget;
static int done_alloc = FALSE;
GdkColormap *cmap;
if (!done_alloc) /* don't do it again */
{
done_alloc = TRUE;
cmap = gtk_widget_get_colormap (widget);
for (i = MAX_COL; i >= 0; i--)
gdk_colormap_alloc_color (cmap, &colors[i], FALSE, TRUE);
}
} }
void void
@@ -247,9 +291,7 @@ palette_load (void)
g_snprintf (prefname, sizeof prefname, "color_%d", i); g_snprintf (prefname, sizeof prefname, "color_%d", i);
if (cfg_get_color (cfg, prefname, &red, &green, &blue)) if (cfg_get_color (cfg, prefname, &red, &green, &blue))
{ {
colors[i].red = red; palette_color_set_rgb16 (&colors[i], red, green, blue);
colors[i].green = green;
colors[i].blue = blue;
} }
} }
@@ -259,9 +301,7 @@ palette_load (void)
g_snprintf (prefname, sizeof prefname, "color_%d", i); g_snprintf (prefname, sizeof prefname, "color_%d", i);
if (cfg_get_color (cfg, prefname, &red, &green, &blue)) if (cfg_get_color (cfg, prefname, &red, &green, &blue))
{ {
colors[j].red = red; palette_color_set_rgb16 (&colors[j], red, green, blue);
colors[j].green = green;
colors[j].blue = blue;
} }
} }
@@ -273,9 +313,7 @@ palette_load (void)
g_snprintf (prefname, sizeof prefname, "dark_color_%d", i); g_snprintf (prefname, sizeof prefname, "dark_color_%d", i);
if (cfg_get_color (cfg, prefname, &red, &green, &blue)) if (cfg_get_color (cfg, prefname, &red, &green, &blue))
{ {
dark_user_colors[i].red = red; palette_color_set_rgb16 (&dark_user_colors[i], red, green, blue);
dark_user_colors[i].green = green;
dark_user_colors[i].blue = blue;
dark_found = TRUE; dark_found = TRUE;
} }
} }
@@ -285,9 +323,7 @@ palette_load (void)
g_snprintf (prefname, sizeof prefname, "dark_color_%d", i); g_snprintf (prefname, sizeof prefname, "dark_color_%d", i);
if (cfg_get_color (cfg, prefname, &red, &green, &blue)) if (cfg_get_color (cfg, prefname, &red, &green, &blue))
{ {
dark_user_colors[j].red = red; palette_color_set_rgb16 (&dark_user_colors[j], red, green, blue);
dark_user_colors[j].green = green;
dark_user_colors[j].blue = blue;
dark_found = TRUE; dark_found = TRUE;
} }
} }
@@ -309,8 +345,8 @@ palette_save (void)
{ {
int i, j, fh; int i, j, fh;
char prefname[256]; char prefname[256];
const GdkColor *lightpal = colors; const PaletteColor *lightpal = colors;
const GdkColor *darkpal = NULL; const PaletteColor *darkpal = NULL;
gboolean dark_mode_active = fe_dark_mode_is_enabled (); gboolean dark_mode_active = fe_dark_mode_is_enabled ();
/* If we're currently in dark mode, keep colors.conf's legacy keys as the user's light palette. */ /* If we're currently in dark mode, keep colors.conf's legacy keys as the user's light palette. */
@@ -343,13 +379,25 @@ palette_save (void)
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
{ {
g_snprintf (prefname, sizeof prefname, "color_%d", i); g_snprintf (prefname, sizeof prefname, "color_%d", i);
cfg_put_color (fh, lightpal[i].red, lightpal[i].green, lightpal[i].blue, prefname); guint16 red;
guint16 green;
guint16 blue;
palette_color_get_rgb16 (&lightpal[i], &red, &green, &blue);
cfg_put_color (fh, red, green, blue, prefname);
} }
for (i = 256, j = 32; j < MAX_COL + 1; i++, j++) for (i = 256, j = 32; j < MAX_COL + 1; i++, j++)
{ {
g_snprintf (prefname, sizeof prefname, "color_%d", i); g_snprintf (prefname, sizeof prefname, "color_%d", i);
cfg_put_color (fh, lightpal[j].red, lightpal[j].green, lightpal[j].blue, prefname); {
guint16 red;
guint16 green;
guint16 blue;
palette_color_get_rgb16 (&lightpal[j], &red, &green, &blue);
cfg_put_color (fh, red, green, blue, prefname);
}
} }
/* Dark palette (new keys) */ /* Dark palette (new keys) */
@@ -358,13 +406,25 @@ palette_save (void)
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
{ {
g_snprintf (prefname, sizeof prefname, "dark_color_%d", i); g_snprintf (prefname, sizeof prefname, "dark_color_%d", i);
cfg_put_color (fh, darkpal[i].red, darkpal[i].green, darkpal[i].blue, prefname); guint16 red;
guint16 green;
guint16 blue;
palette_color_get_rgb16 (&darkpal[i], &red, &green, &blue);
cfg_put_color (fh, red, green, blue, prefname);
} }
for (i = 256, j = 32; j < MAX_COL + 1; i++, j++) for (i = 256, j = 32; j < MAX_COL + 1; i++, j++)
{ {
g_snprintf (prefname, sizeof prefname, "dark_color_%d", i); g_snprintf (prefname, sizeof prefname, "dark_color_%d", i);
cfg_put_color (fh, darkpal[j].red, darkpal[j].green, darkpal[j].blue, prefname); {
guint16 red;
guint16 green;
guint16 blue;
palette_color_get_rgb16 (&darkpal[j], &red, &green, &blue);
cfg_put_color (fh, red, green, blue, prefname);
}
} }
} }
@@ -374,16 +434,25 @@ palette_save (void)
static gboolean static gboolean
palette_color_eq (const GdkColor *a, const GdkColor *b) palette_color_eq (const PaletteColor *a, const PaletteColor *b)
{ {
return a->red == b->red && a->green == b->green && a->blue == b->blue; guint16 red_a;
guint16 green_a;
guint16 blue_a;
guint16 red_b;
guint16 green_b;
guint16 blue_b;
palette_color_get_rgb16 (a, &red_a, &green_a, &blue_a);
palette_color_get_rgb16 (b, &red_b, &green_b, &blue_b);
return red_a == red_b && green_a == green_b && blue_a == blue_b;
} }
gboolean gboolean
palette_apply_dark_mode (gboolean enable) palette_apply_dark_mode (gboolean enable)
{ {
GdkColor old_colors[MAX_COL + 1]; PaletteColor old_colors[MAX_COL + 1];
GdkColormap *cmap;
int i; int i;
gboolean changed = FALSE; gboolean changed = FALSE;
@@ -406,16 +475,12 @@ palette_apply_dark_mode (gboolean enable)
else else
memcpy (colors, user_colors, sizeof (colors)); memcpy (colors, user_colors, sizeof (colors));
/* Allocate the new colors for GTK's colormap. */ /* Track whether any palette entries changed. */
cmap = gdk_colormap_get_system (); (void) i;
for (i = 0; i <= MAX_COL; i++)
gdk_colormap_alloc_color (cmap, &colors[i], FALSE, TRUE);
for (i = 0; i <= MAX_COL; i++) for (i = 0; i <= MAX_COL; i++)
{ {
if (old_colors[i].red != colors[i].red || if (!palette_color_eq (&old_colors[i], &colors[i]))
old_colors[i].green != colors[i].green ||
old_colors[i].blue != colors[i].blue)
{ {
changed = TRUE; changed = TRUE;
break; break;

View File

@@ -24,7 +24,31 @@
#include "xtext-color.h" #include "xtext-color.h"
extern GdkColor colors[]; #if HAVE_GTK3
typedef GdkRGBA PaletteColor;
#define PALETTE_GDK_TYPE GDK_TYPE_RGBA
#define PALETTE_FOREGROUND_PROPERTY "foreground-rgba"
#else
typedef GdkColor PaletteColor;
#define PALETTE_GDK_TYPE GDK_TYPE_COLOR
#define PALETTE_FOREGROUND_PROPERTY "foreground-gdk"
#endif
extern PaletteColor colors[];
static inline void
palette_color_get_rgb16 (const PaletteColor *color, guint16 *red, guint16 *green, guint16 *blue)
{
#if HAVE_GTK3
*red = (guint16) CLAMP (color->red * 65535.0 + 0.5, 0.0, 65535.0);
*green = (guint16) CLAMP (color->green * 65535.0 + 0.5, 0.0, 65535.0);
*blue = (guint16) CLAMP (color->blue * 65535.0 + 0.5, 0.0, 65535.0);
#else
*red = color->red;
*green = color->green;
*blue = color->blue;
#endif
}
#define COL_MARK_FG 32 #define COL_MARK_FG 32
#define COL_MARK_BG 33 #define COL_MARK_BG 33
@@ -43,8 +67,8 @@ void palette_load (void);
void palette_save (void); void palette_save (void);
/* Keep a copy of the user's palette so dark mode can be toggled without losing it. */ /* Keep a copy of the user's palette so dark mode can be toggled without losing it. */
void palette_user_set_color (int idx, const GdkColor *col); void palette_user_set_color (int idx, const PaletteColor *col);
void palette_dark_set_color (int idx, const GdkColor *col); void palette_dark_set_color (int idx, const PaletteColor *col);
/* /*
* Apply ZoiteChat's built-in "dark mode" palette. * Apply ZoiteChat's built-in "dark mode" palette.

View File

@@ -31,18 +31,39 @@
#include "menu.h" #include "menu.h"
#include "gtkutil.h" #include "gtkutil.h"
#if HAVE_GTK3
#include <gio/gio.h>
#if defined(GTK_DISABLE_DEPRECATED)
typedef struct _GtkStatusIcon GtkStatusIcon;
#endif
#ifndef WIN32
#if defined(HAVE_AYATANA_APPINDICATOR)
#include <libayatana-appindicator/app-indicator.h>
#elif defined(HAVE_APPINDICATOR)
#include <libappindicator/app-indicator.h>
#endif
#endif
#define ICON_TRAY_PREFERENCES "preferences-system"
#define ICON_TRAY_QUIT "application-exit"
#else
#define ICON_TRAY_PREFERENCES GTK_STOCK_PREFERENCES
#define ICON_TRAY_QUIT GTK_STOCK_QUIT
#endif
#ifndef WIN32 #ifndef WIN32
#include <unistd.h> #include <unistd.h>
#endif #endif
typedef enum /* current icon status */ typedef enum /* current icon status */
{ {
TS_NONE, TRAY_ICON_NONE,
TS_MESSAGE, TRAY_ICON_NORMAL,
TS_HIGHLIGHT, TRAY_ICON_MESSAGE,
TS_FILEOFFER, TRAY_ICON_HIGHLIGHT,
TS_CUSTOM /* plugin */ TRAY_ICON_FILEOFFER,
} TrayStatus; TRAY_ICON_CUSTOM1,
TRAY_ICON_CUSTOM2
} TrayIconState;
typedef enum typedef enum
{ {
@@ -51,7 +72,37 @@ typedef enum
WS_HIDDEN WS_HIDDEN
} WinStatus; } WinStatus;
#if HAVE_GTK3 && !defined(WIN32) && (defined(HAVE_AYATANA_APPINDICATOR) || defined(HAVE_APPINDICATOR))
#define HAVE_APPINDICATOR_BACKEND 1
#else
#define HAVE_APPINDICATOR_BACKEND 0
#endif
#if HAVE_APPINDICATOR_BACKEND
/* GTK3: use AppIndicator/StatusNotifier item for tray integration. */
typedef GIcon *TrayIcon;
typedef GIcon *TrayCustomIcon;
#define tray_icon_free(i) g_object_unref(i)
#define ICON_NORMAL_NAME "net.zoite.Zoitechat"
#define ICON_MSG_NAME "mail-unread"
#define ICON_HILIGHT_NAME "dialog-warning"
#define ICON_FILE_NAME "folder-download"
static TrayIcon tray_icon_normal;
static TrayIcon tray_icon_msg;
static TrayIcon tray_icon_hilight;
static TrayIcon tray_icon_file;
#define ICON_NORMAL tray_icon_normal
#define ICON_MSG tray_icon_msg
#define ICON_HILIGHT tray_icon_hilight
#define ICON_FILE tray_icon_file
#endif
#if !HAVE_APPINDICATOR_BACKEND
typedef GdkPixbuf* TrayIcon; typedef GdkPixbuf* TrayIcon;
typedef GdkPixbuf* TrayCustomIcon;
#define tray_icon_from_file(f) gdk_pixbuf_new_from_file(f,NULL) #define tray_icon_from_file(f) gdk_pixbuf_new_from_file(f,NULL)
#define tray_icon_free(i) g_object_unref(i) #define tray_icon_free(i) g_object_unref(i)
@@ -59,19 +110,59 @@ typedef GdkPixbuf* TrayIcon;
#define ICON_MSG pix_tray_message #define ICON_MSG pix_tray_message
#define ICON_HILIGHT pix_tray_highlight #define ICON_HILIGHT pix_tray_highlight
#define ICON_FILE pix_tray_fileoffer #define ICON_FILE pix_tray_fileoffer
#endif
#if HAVE_GTK3 && defined(GTK_DISABLE_DEPRECATED) && !HAVE_APPINDICATOR_BACKEND
GtkStatusIcon *gtk_status_icon_new_from_pixbuf (GdkPixbuf *pixbuf);
void gtk_status_icon_set_from_pixbuf (GtkStatusIcon *status_icon, GdkPixbuf *pixbuf);
void gtk_status_icon_set_tooltip_text (GtkStatusIcon *status_icon, const gchar *text);
gboolean gtk_status_icon_is_embedded (GtkStatusIcon *status_icon);
#endif
#define TIMEOUT 500 #define TIMEOUT 500
static GtkStatusIcon *sticon; void tray_apply_setup (void);
static gboolean tray_menu_try_restore (void);
static void tray_cleanup (void);
static void tray_init (void);
static void tray_set_icon_state (TrayIcon icon, TrayIconState state);
static void tray_menu_restore_cb (GtkWidget *item, gpointer userdata);
static void tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data);
#if HAVE_APPINDICATOR_BACKEND
static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata);
#endif
#if !HAVE_APPINDICATOR_BACKEND
static void tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata);
#endif
typedef struct
{
gboolean (*init)(void);
void (*set_icon)(TrayIcon icon);
void (*set_tooltip)(const char *text);
gboolean (*is_embedded)(void);
void (*cleanup)(void);
} TrayBackendOps;
#if HAVE_APPINDICATOR_BACKEND
static AppIndicator *tray_indicator;
static GtkWidget *tray_menu;
#endif
#if !HAVE_APPINDICATOR_BACKEND
static GtkStatusIcon *tray_status_icon;
#endif
static gboolean tray_backend_active = FALSE;
static gint flash_tag; static gint flash_tag;
static TrayStatus tray_status; static TrayIconState tray_icon_state;
#ifdef WIN32 static TrayIcon tray_flash_icon;
static TrayIconState tray_flash_state;
#if defined(WIN32)
static guint tray_menu_timer; static guint tray_menu_timer;
static gint64 tray_menu_inactivetime; static gint64 tray_menu_inactivetime;
#endif #endif
static zoitechat_plugin *ph; static zoitechat_plugin *ph;
static TrayIcon custom_icon1; static TrayCustomIcon custom_icon1;
static TrayIcon custom_icon2; static TrayCustomIcon custom_icon2;
static int tray_priv_count = 0; static int tray_priv_count = 0;
static int tray_pub_count = 0; static int tray_pub_count = 0;
@@ -79,12 +170,401 @@ static int tray_hilight_count = 0;
static int tray_file_count = 0; static int tray_file_count = 0;
static int tray_restore_timer = 0; static int tray_restore_timer = 0;
#if HAVE_APPINDICATOR_BACKEND
static TrayCustomIcon
tray_icon_from_file (const char *filename)
{
GFile *file;
TrayCustomIcon icon;
void tray_apply_setup (void); if (!filename)
static gboolean tray_menu_try_restore (void); return NULL;
static void tray_cleanup (void);
static void tray_init (void);
file = g_file_new_for_path (filename);
icon = g_file_icon_new (file);
g_object_unref (file);
return icon;
}
static char *
tray_gtk3_cache_pixbuf_icon (const char *basename, GdkPixbuf *pixbuf)
{
char *cache_dir;
char *filename;
char *path;
if (!pixbuf || !basename)
return NULL;
cache_dir = g_build_filename (g_get_user_cache_dir (), "zoitechat", "tray-icons", NULL);
if (g_mkdir_with_parents (cache_dir, 0700) != 0)
{
g_free (cache_dir);
return NULL;
}
filename = g_strdup_printf ("%s.png", basename);
path = g_build_filename (cache_dir, filename, NULL);
g_free (filename);
g_free (cache_dir);
if (!g_file_test (path, G_FILE_TEST_EXISTS))
gdk_pixbuf_save (pixbuf, path, "png", NULL, NULL);
return path;
}
static char *
tray_gtk3_fallback_icon_path_for_name (const char *name)
{
if (g_strcmp0 (name, ICON_NORMAL_NAME) == 0)
return tray_gtk3_cache_pixbuf_icon ("tray_normal", pix_tray_normal);
if (g_strcmp0 (name, ICON_MSG_NAME) == 0)
return tray_gtk3_cache_pixbuf_icon ("tray_message", pix_tray_message);
if (g_strcmp0 (name, ICON_HILIGHT_NAME) == 0)
return tray_gtk3_cache_pixbuf_icon ("tray_highlight", pix_tray_highlight);
if (g_strcmp0 (name, ICON_FILE_NAME) == 0)
return tray_gtk3_cache_pixbuf_icon ("tray_fileoffer", pix_tray_fileoffer);
return NULL;
}
static void
tray_gtk3_icons_init (void)
{
if (!tray_icon_normal)
tray_icon_normal = g_themed_icon_new (ICON_NORMAL_NAME);
if (!tray_icon_msg)
tray_icon_msg = g_themed_icon_new (ICON_MSG_NAME);
if (!tray_icon_hilight)
tray_icon_hilight = g_themed_icon_new (ICON_HILIGHT_NAME);
if (!tray_icon_file)
tray_icon_file = g_themed_icon_new (ICON_FILE_NAME);
}
static void
tray_gtk3_icons_cleanup (void)
{
g_clear_object (&tray_icon_normal);
g_clear_object (&tray_icon_msg);
g_clear_object (&tray_icon_hilight);
g_clear_object (&tray_icon_file);
}
static GtkIconTheme *tray_gtk3_icon_theme = NULL;
static gulong tray_gtk3_icon_theme_changed_handler = 0;
static void
tray_gtk3_reapply_icon_state (void)
{
switch (tray_icon_state)
{
case TRAY_ICON_NORMAL:
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
break;
case TRAY_ICON_MESSAGE:
tray_set_icon_state (ICON_MSG, TRAY_ICON_MESSAGE);
break;
case TRAY_ICON_HIGHLIGHT:
tray_set_icon_state (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
break;
case TRAY_ICON_FILEOFFER:
tray_set_icon_state (ICON_FILE, TRAY_ICON_FILEOFFER);
break;
case TRAY_ICON_CUSTOM1:
tray_set_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
break;
case TRAY_ICON_CUSTOM2:
tray_set_icon_state (custom_icon2, TRAY_ICON_CUSTOM2);
break;
case TRAY_ICON_NONE:
default:
break;
}
}
static void
tray_gtk3_theme_changed_cb (GtkIconTheme *theme, gpointer user_data)
{
(void)theme;
(void)user_data;
if (!tray_backend_active)
return;
tray_gtk3_icons_cleanup ();
tray_gtk3_icons_init ();
tray_gtk3_reapply_icon_state ();
}
static const char *
tray_gtk3_icon_to_name (TrayIcon icon, char **allocated)
{
const char * const *names;
GtkIconTheme *theme;
GFile *file;
if (!icon)
return NULL;
if (G_IS_THEMED_ICON (icon))
{
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
if (names && names[0])
{
theme = gtk_icon_theme_get_default ();
if (theme && gtk_icon_theme_has_icon (theme, names[0]))
return names[0];
*allocated = tray_gtk3_fallback_icon_path_for_name (names[0]);
if (*allocated)
return *allocated;
}
}
if (G_IS_FILE_ICON (icon))
{
file = g_file_icon_get_file (G_FILE_ICON (icon));
if (file)
{
*allocated = g_file_get_path (file);
if (*allocated)
return *allocated;
}
}
*allocated = g_icon_to_string (icon);
return *allocated;
}
static void
tray_app_indicator_set_icon (TrayIcon icon)
{
char *icon_name_alloc = NULL;
const char *icon_name;
if (!tray_indicator)
return;
icon_name = tray_gtk3_icon_to_name (icon, &icon_name_alloc);
if (!icon_name)
return;
app_indicator_set_icon_full (tray_indicator, icon_name, _(DISPLAY_NAME));
app_indicator_set_status (tray_indicator, APP_INDICATOR_STATUS_ACTIVE);
g_free (icon_name_alloc);
}
static void
tray_app_indicator_set_tooltip (const char *text)
{
if (!tray_indicator)
return;
app_indicator_set_title (tray_indicator, text ? text : "");
}
static gboolean
tray_app_indicator_is_embedded (void)
{
gboolean connected = TRUE;
GObjectClass *klass;
if (!tray_indicator)
return FALSE;
klass = G_OBJECT_GET_CLASS (tray_indicator);
if (klass && g_object_class_find_property (klass, "connected"))
{
g_object_get (tray_indicator, "connected", &connected, NULL);
}
return connected;
}
static void
tray_app_indicator_cleanup (void)
{
if (tray_indicator)
{
g_object_unref (tray_indicator);
tray_indicator = NULL;
}
if (tray_menu)
{
gtk_widget_destroy (tray_menu);
tray_menu = NULL;
}
}
static gboolean
tray_app_indicator_init (void)
{
GObjectClass *klass;
tray_indicator = app_indicator_new ("zoitechat", ICON_NORMAL_NAME,
APP_INDICATOR_CATEGORY_COMMUNICATIONS);
if (!tray_indicator)
return FALSE;
tray_menu = gtk_menu_new ();
g_signal_connect (G_OBJECT (tray_menu), "show",
G_CALLBACK (tray_menu_show_cb), NULL);
app_indicator_set_menu (tray_indicator, GTK_MENU (tray_menu));
app_indicator_set_status (tray_indicator, APP_INDICATOR_STATUS_ACTIVE);
klass = G_OBJECT_GET_CLASS (tray_indicator);
if (klass && g_object_class_find_property (klass, "connected"))
{
g_signal_connect (G_OBJECT (tray_indicator), "notify::connected",
G_CALLBACK (tray_menu_notify_cb), NULL);
}
return TRUE;
}
static const TrayBackendOps tray_backend_ops = {
tray_app_indicator_init,
tray_app_indicator_set_icon,
tray_app_indicator_set_tooltip,
tray_app_indicator_is_embedded,
tray_app_indicator_cleanup
};
#endif
#if !HAVE_APPINDICATOR_BACKEND
static void
tray_status_icon_set_icon (TrayIcon icon)
{
if (!tray_status_icon)
return;
gtk_status_icon_set_from_pixbuf (tray_status_icon, icon);
}
static void
tray_status_icon_set_tooltip (const char *text)
{
if (!tray_status_icon)
return;
gtk_status_icon_set_tooltip_text (tray_status_icon, text);
}
static gboolean
tray_status_icon_is_embedded (void)
{
if (!tray_status_icon)
return FALSE;
return gtk_status_icon_is_embedded (tray_status_icon);
}
static void
tray_status_icon_cleanup (void)
{
if (tray_status_icon)
{
g_object_unref (tray_status_icon);
tray_status_icon = NULL;
}
}
static gboolean
tray_status_icon_init (void)
{
tray_status_icon = gtk_status_icon_new_from_pixbuf (ICON_NORMAL);
if (!tray_status_icon)
return FALSE;
g_signal_connect (G_OBJECT (tray_status_icon), "popup-menu",
G_CALLBACK (tray_menu_cb), tray_status_icon);
g_signal_connect (G_OBJECT (tray_status_icon), "activate",
G_CALLBACK (tray_menu_restore_cb), NULL);
g_signal_connect (G_OBJECT (tray_status_icon), "notify::embedded",
G_CALLBACK (tray_menu_notify_cb), NULL);
return TRUE;
}
static const TrayBackendOps tray_backend_ops = {
tray_status_icon_init,
tray_status_icon_set_icon,
tray_status_icon_set_tooltip,
tray_status_icon_is_embedded,
tray_status_icon_cleanup
};
#endif
static gboolean
tray_backend_init (void)
{
if (!tray_backend_ops.init)
return FALSE;
#if HAVE_APPINDICATOR_BACKEND
tray_gtk3_icons_init ();
if (!tray_gtk3_icon_theme)
tray_gtk3_icon_theme = gtk_icon_theme_get_default ();
if (tray_gtk3_icon_theme && tray_gtk3_icon_theme_changed_handler == 0)
{
tray_gtk3_icon_theme_changed_handler = g_signal_connect (
tray_gtk3_icon_theme,
"changed",
G_CALLBACK (tray_gtk3_theme_changed_cb),
NULL);
}
#endif
tray_backend_active = tray_backend_ops.init ();
return tray_backend_active;
}
static void
tray_backend_set_icon (TrayIcon icon)
{
if (tray_backend_active && tray_backend_ops.set_icon)
tray_backend_ops.set_icon (icon);
}
static void
tray_backend_set_tooltip (const char *text)
{
if (tray_backend_active && tray_backend_ops.set_tooltip)
tray_backend_ops.set_tooltip (text);
}
static gboolean
tray_backend_is_embedded (void)
{
if (!tray_backend_active || !tray_backend_ops.is_embedded)
return FALSE;
return tray_backend_ops.is_embedded ();
}
static void
tray_backend_cleanup (void)
{
if (tray_backend_ops.cleanup)
tray_backend_ops.cleanup ();
#if HAVE_APPINDICATOR_BACKEND
if (tray_gtk3_icon_theme && tray_gtk3_icon_theme_changed_handler)
{
g_signal_handler_disconnect (tray_gtk3_icon_theme,
tray_gtk3_icon_theme_changed_handler);
tray_gtk3_icon_theme_changed_handler = 0;
}
tray_gtk3_icon_theme = NULL;
tray_gtk3_icons_cleanup ();
#endif
tray_backend_active = FALSE;
}
static WinStatus static WinStatus
tray_get_window_status (void) tray_get_window_status (void)
@@ -136,11 +616,27 @@ tray_count_networks (void)
return cons; return cons;
} }
static void
tray_set_icon_state (TrayIcon icon, TrayIconState state)
{
tray_backend_set_icon (icon);
tray_icon_state = state;
}
static void
tray_set_custom_icon_state (TrayCustomIcon icon, TrayIconState state)
{
tray_backend_set_icon (icon);
tray_icon_state = state;
}
void void
fe_tray_set_tooltip (const char *text) fe_tray_set_tooltip (const char *text)
{ {
if (sticon) if (!tray_backend_active)
gtk_status_icon_set_tooltip_text (sticon, text); return;
tray_backend_set_tooltip (text);
} }
static void static void
@@ -168,9 +664,9 @@ tray_stop_flash (void)
flash_tag = 0; flash_tag = 0;
} }
if (sticon) if (tray_backend_active)
{ {
gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL); tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
nets = tray_count_networks (); nets = tray_count_networks ();
chans = tray_count_channels (); chans = tray_count_channels ();
if (nets) if (nets)
@@ -192,7 +688,8 @@ tray_stop_flash (void)
custom_icon2 = NULL; custom_icon2 = NULL;
} }
tray_status = TS_NONE; tray_flash_icon = NULL;
tray_flash_state = TRAY_ICON_NONE;
} }
static void static void
@@ -205,40 +702,42 @@ tray_reset_counts (void)
} }
static int static int
tray_timeout_cb (TrayIcon icon) tray_timeout_cb (gpointer userdata)
{ {
(void)userdata;
if (custom_icon1) if (custom_icon1)
{ {
if (gtk_status_icon_get_pixbuf (sticon) == custom_icon1) if (tray_icon_state == TRAY_ICON_CUSTOM1)
{ {
if (custom_icon2) if (custom_icon2)
gtk_status_icon_set_from_pixbuf (sticon, custom_icon2); tray_set_custom_icon_state (custom_icon2, TRAY_ICON_CUSTOM2);
else else
gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL); tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
} }
else else
{ {
gtk_status_icon_set_from_pixbuf (sticon, custom_icon1); tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
} }
} }
else else
{ {
if (gtk_status_icon_get_pixbuf (sticon) == ICON_NORMAL) if (tray_icon_state == TRAY_ICON_NORMAL)
gtk_status_icon_set_from_pixbuf (sticon, icon); tray_set_icon_state (tray_flash_icon, tray_flash_state);
else else
gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL); tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
} }
return 1; return 1;
} }
static void static void
tray_set_flash (TrayIcon icon) tray_set_flash (TrayIcon icon, TrayIconState state)
{ {
if (!sticon) if (!tray_backend_active)
return; return;
/* already flashing the same icon */ /* already flashing the same icon */
if (flash_tag && gtk_status_icon_get_pixbuf (sticon) == icon) if (flash_tag && tray_icon_state == state)
return; return;
/* no flashing if window is focused */ /* no flashing if window is focused */
@@ -247,16 +746,18 @@ tray_set_flash (TrayIcon icon)
tray_stop_flash (); tray_stop_flash ();
gtk_status_icon_set_from_pixbuf (sticon, icon); tray_flash_icon = icon;
tray_flash_state = state;
tray_set_icon_state (icon, state);
if (prefs.hex_gui_tray_blink) if (prefs.hex_gui_tray_blink)
flash_tag = g_timeout_add (TIMEOUT, (GSourceFunc) tray_timeout_cb, icon); flash_tag = g_timeout_add (TIMEOUT, (GSourceFunc) tray_timeout_cb, NULL);
} }
void void
fe_tray_set_flash (const char *filename1, const char *filename2, int tout) fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
{ {
tray_apply_setup (); tray_apply_setup ();
if (!sticon) if (!tray_backend_active)
return; return;
tray_stop_flash (); tray_stop_flash ();
@@ -268,16 +769,15 @@ fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
if (filename2) if (filename2)
custom_icon2 = tray_icon_from_file (filename2); custom_icon2 = tray_icon_from_file (filename2);
gtk_status_icon_set_from_pixbuf (sticon, custom_icon1); tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
flash_tag = g_timeout_add (tout, (GSourceFunc) tray_timeout_cb, NULL); flash_tag = g_timeout_add (tout, (GSourceFunc) tray_timeout_cb, NULL);
tray_status = TS_CUSTOM;
} }
void void
fe_tray_set_icon (feicon icon) fe_tray_set_icon (feicon icon)
{ {
tray_apply_setup (); tray_apply_setup ();
if (!sticon) if (!tray_backend_active)
return; return;
tray_stop_flash (); tray_stop_flash ();
@@ -288,13 +788,13 @@ fe_tray_set_icon (feicon icon)
break; break;
case FE_ICON_MESSAGE: case FE_ICON_MESSAGE:
case FE_ICON_PRIVMSG: case FE_ICON_PRIVMSG:
tray_set_flash (ICON_MSG); tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
break; break;
case FE_ICON_HIGHLIGHT: case FE_ICON_HIGHLIGHT:
tray_set_flash (ICON_HILIGHT); tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
break; break;
case FE_ICON_FILEOFFER: case FE_ICON_FILEOFFER:
tray_set_flash (ICON_FILE); tray_set_flash (ICON_FILE, TRAY_ICON_FILEOFFER);
} }
} }
@@ -302,7 +802,7 @@ void
fe_tray_set_file (const char *filename) fe_tray_set_file (const char *filename)
{ {
tray_apply_setup (); tray_apply_setup ();
if (!sticon) if (!tray_backend_active)
return; return;
tray_stop_flash (); tray_stop_flash ();
@@ -310,8 +810,7 @@ fe_tray_set_file (const char *filename)
if (filename) if (filename)
{ {
custom_icon1 = tray_icon_from_file (filename); custom_icon1 = tray_icon_from_file (filename);
gtk_status_icon_set_from_pixbuf (sticon, custom_icon1); tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
tray_status = TS_CUSTOM;
} }
} }
@@ -324,7 +823,7 @@ tray_toggle_visibility (gboolean force_hide)
static int fullscreen; static int fullscreen;
GtkWindow *win; GtkWindow *win;
if (!sticon) if (!tray_backend_active)
return FALSE; return FALSE;
/* ph may have an invalid context now */ /* ph may have an invalid context now */
@@ -369,15 +868,22 @@ tray_toggle_visibility (gboolean force_hide)
static void static void
tray_menu_restore_cb (GtkWidget *item, gpointer userdata) tray_menu_restore_cb (GtkWidget *item, gpointer userdata)
{ {
(void)item;
(void)userdata;
tray_toggle_visibility (FALSE); tray_toggle_visibility (FALSE);
} }
static void static void
tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data) tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data)
{ {
if (sticon) (void)tray;
(void)pspec;
(void)user_data;
if (tray_backend_active)
{ {
if (!gtk_status_icon_is_embedded (sticon)) if (!tray_backend_is_embedded ())
{ {
tray_restore_timer = g_timeout_add(500, (GSourceFunc)tray_menu_try_restore, NULL); tray_restore_timer = g_timeout_add(500, (GSourceFunc)tray_menu_try_restore, NULL);
} }
@@ -403,6 +909,9 @@ tray_menu_try_restore (void)
static void static void
tray_menu_quit_cb (GtkWidget *item, gpointer userdata) tray_menu_quit_cb (GtkWidget *item, gpointer userdata)
{ {
(void)item;
(void)userdata;
mg_open_quit_dialog (FALSE); mg_open_quit_dialog (FALSE);
} }
@@ -483,6 +992,8 @@ blink_item (unsigned int *setting, GtkWidget *menu, char *label)
static void static void
tray_menu_destroy (GtkWidget *menu, gpointer userdata) tray_menu_destroy (GtkWidget *menu, gpointer userdata)
{ {
(void)userdata;
gtk_widget_destroy (menu); gtk_widget_destroy (menu);
g_object_unref (menu); g_object_unref (menu);
#ifdef WIN32 #ifdef WIN32
@@ -494,6 +1005,8 @@ tray_menu_destroy (GtkWidget *menu, gpointer userdata)
static gboolean static gboolean
tray_menu_enter_cb (GtkWidget *menu) tray_menu_enter_cb (GtkWidget *menu)
{ {
(void)menu;
tray_menu_inactivetime = 0; tray_menu_inactivetime = 0;
return FALSE; return FALSE;
} }
@@ -501,6 +1014,8 @@ tray_menu_enter_cb (GtkWidget *menu)
static gboolean static gboolean
tray_menu_left_cb (GtkWidget *menu) tray_menu_left_cb (GtkWidget *menu)
{ {
(void)menu;
tray_menu_inactivetime = g_get_real_time (); tray_menu_inactivetime = g_get_real_time ();
return FALSE; return FALSE;
} }
@@ -521,14 +1036,16 @@ tray_check_hide (GtkWidget *menu)
static void static void
tray_menu_settings (GtkWidget * wid, gpointer none) tray_menu_settings (GtkWidget * wid, gpointer none)
{ {
(void)wid;
(void)none;
extern void setup_open (void); extern void setup_open (void);
setup_open (); setup_open ();
} }
static void static void
tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata) tray_menu_populate (GtkWidget *menu)
{ {
static GtkWidget *menu;
GtkWidget *submenu; GtkWidget *submenu;
GtkWidget *item; GtkWidget *item;
int away_status; int away_status;
@@ -536,15 +1053,6 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
/* ph may have an invalid context now */ /* ph may have an invalid context now */
zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL)); zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL));
/* close any old menu */
if (G_IS_OBJECT (menu))
{
tray_menu_destroy (menu, NULL);
}
menu = gtk_menu_new ();
/*gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (widget));*/
if (tray_get_window_status () == WS_HIDDEN) if (tray_get_window_status () == WS_HIDDEN)
tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL); tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL);
else else
@@ -574,59 +1082,96 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
menu_add_plugin_items (menu, "\x5$TRAY", NULL); menu_add_plugin_items (menu, "\x5$TRAY", NULL);
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL); tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
mg_create_icon_item (_("_Preferences"), GTK_STOCK_PREFERENCES, menu, tray_menu_settings, NULL); mg_create_icon_item (_("_Preferences"), ICON_TRAY_PREFERENCES, menu, tray_menu_settings, NULL);
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL); tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
mg_create_icon_item (_("_Quit"), GTK_STOCK_QUIT, menu, tray_menu_quit_cb, NULL); mg_create_icon_item (_("_Quit"), ICON_TRAY_QUIT, menu, tray_menu_quit_cb, NULL);
}
#if HAVE_GTK3 && !defined(WIN32)
static void
tray_menu_clear (GtkWidget *menu)
{
GList *children;
GList *iter;
children = gtk_container_get_children (GTK_CONTAINER (menu));
for (iter = children; iter; iter = iter->next)
gtk_widget_destroy (GTK_WIDGET (iter->data));
g_list_free (children);
}
static void
tray_menu_show_cb (GtkWidget *menu, gpointer userdata)
{
(void)userdata;
tray_menu_clear (menu);
tray_menu_populate (menu);
}
#endif
#if !HAVE_APPINDICATOR_BACKEND
static void
tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
{
static GtkWidget *menu;
(void)widget;
/* close any old menu */
if (G_IS_OBJECT (menu))
{
tray_menu_destroy (menu, NULL);
}
menu = gtk_menu_new ();
/*gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (widget));*/
tray_menu_populate (menu);
g_object_ref (menu); g_object_ref (menu);
g_object_ref_sink (menu); g_object_ref_sink (menu);
g_object_unref (menu); g_object_unref (menu);
g_signal_connect (G_OBJECT (menu), "selection-done", g_signal_connect (G_OBJECT (menu), "selection-done",
G_CALLBACK (tray_menu_destroy), NULL); G_CALLBACK (tray_menu_destroy), NULL);
#ifdef WIN32 #ifdef WIN32
g_signal_connect (G_OBJECT (menu), "leave-notify-event", g_signal_connect (G_OBJECT (menu), "leave-notify-event",
G_CALLBACK (tray_menu_left_cb), NULL); G_CALLBACK (tray_menu_left_cb), NULL);
g_signal_connect (G_OBJECT (menu), "enter-notify-event", g_signal_connect (G_OBJECT (menu), "enter-notify-event",
G_CALLBACK (tray_menu_enter_cb), NULL); G_CALLBACK (tray_menu_enter_cb), NULL);
tray_menu_timer = g_timeout_add (500, (GSourceFunc)tray_check_hide, menu); tray_menu_timer = g_timeout_add (500, (GSourceFunc)tray_check_hide, menu);
#endif #endif
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL,
userdata, button, time); userdata, button, time);
} }
#endif
static void static void
tray_init (void) tray_init (void)
{ {
flash_tag = 0; flash_tag = 0;
tray_status = TS_NONE; tray_icon_state = TRAY_ICON_NONE;
tray_flash_icon = NULL;
tray_flash_state = TRAY_ICON_NONE;
custom_icon1 = NULL; custom_icon1 = NULL;
custom_icon2 = NULL; custom_icon2 = NULL;
sticon = gtk_status_icon_new_from_pixbuf (ICON_NORMAL); if (!tray_backend_init ())
if (!sticon)
return; return;
tray_icon_state = TRAY_ICON_NORMAL;
g_signal_connect (G_OBJECT (sticon), "popup-menu", tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
G_CALLBACK (tray_menu_cb), sticon);
g_signal_connect (G_OBJECT (sticon), "activate",
G_CALLBACK (tray_menu_restore_cb), NULL);
g_signal_connect (G_OBJECT (sticon), "notify::embedded",
G_CALLBACK (tray_menu_notify_cb), NULL);
} }
static int static int
tray_hilight_cb (char *word[], void *userdata) tray_hilight_cb (char *word[], void *userdata)
{ {
/*if (tray_status == TS_HIGHLIGHT) /*if (tray_icon_state == TRAY_ICON_HIGHLIGHT)
return ZOITECHAT_EAT_NONE;*/ return ZOITECHAT_EAT_NONE;*/
if (prefs.hex_input_tray_hilight) if (prefs.hex_input_tray_hilight)
{ {
tray_set_flash (ICON_HILIGHT); tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
/* FIXME: hides any previous private messages */ /* FIXME: hides any previous private messages */
tray_hilight_count++; tray_hilight_count++;
@@ -645,12 +1190,12 @@ tray_hilight_cb (char *word[], void *userdata)
static int static int
tray_message_cb (char *word[], void *userdata) tray_message_cb (char *word[], void *userdata)
{ {
if (/*tray_status == TS_MESSAGE ||*/ tray_status == TS_HIGHLIGHT) if (/*tray_icon_state == TRAY_ICON_MESSAGE ||*/ tray_icon_state == TRAY_ICON_HIGHLIGHT)
return ZOITECHAT_EAT_NONE; return ZOITECHAT_EAT_NONE;
if (prefs.hex_input_tray_chans) if (prefs.hex_input_tray_chans)
{ {
tray_set_flash (ICON_MSG); tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
tray_pub_count++; tray_pub_count++;
if (tray_pub_count == 1) if (tray_pub_count == 1)
@@ -677,7 +1222,7 @@ tray_priv (char *from, char *text)
if (prefs.hex_input_tray_priv) if (prefs.hex_input_tray_priv)
{ {
tray_set_flash (ICON_MSG); tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
tray_priv_count++; tray_priv_count++;
if (tray_priv_count == 1) if (tray_priv_count == 1)
@@ -711,7 +1256,7 @@ tray_dcc_cb (char *word[], void *userdata)
{ {
const char *network; const char *network;
/* if (tray_status == TS_FILEOFFER) /* if (tray_icon_state == TRAY_ICON_FILEOFFER)
return ZOITECHAT_EAT_NONE;*/ return ZOITECHAT_EAT_NONE;*/
network = zoitechat_get_info (ph, "network"); network = zoitechat_get_info (ph, "network");
@@ -720,7 +1265,7 @@ tray_dcc_cb (char *word[], void *userdata)
if (prefs.hex_input_tray_priv && (!prefs.hex_away_omit_alerts || tray_find_away_status () != 1)) if (prefs.hex_input_tray_priv && (!prefs.hex_away_omit_alerts || tray_find_away_status () != 1))
{ {
tray_set_flash (ICON_FILE); tray_set_flash (ICON_FILE, TRAY_ICON_FILEOFFER);
tray_file_count++; tray_file_count++;
if (tray_file_count == 1) if (tray_file_count == 1)
@@ -747,17 +1292,14 @@ tray_cleanup (void)
{ {
tray_stop_flash (); tray_stop_flash ();
if (sticon) if (tray_backend_active)
{ tray_backend_cleanup ();
g_object_unref ((GObject *)sticon);
sticon = NULL;
}
} }
void void
tray_apply_setup (void) tray_apply_setup (void)
{ {
if (sticon) if (tray_backend_active)
{ {
if (!prefs.hex_gui_tray) if (!prefs.hex_gui_tray)
tray_cleanup (); tray_cleanup ();

View File

@@ -48,6 +48,54 @@ enum
static GtkWidget *plugin_window = NULL; static GtkWidget *plugin_window = NULL;
static const char *
plugingui_safe_string (const char *value)
{
return value ? value : "";
}
static session *
plugingui_get_target_session (void)
{
if (is_session (current_sess))
return current_sess;
fe_message (_("No active session available for addon command."), FE_MSG_ERROR);
return NULL;
}
#if HAVE_GTK3
#define ICON_PLUGIN_LOAD "document-open"
#define ICON_PLUGIN_UNLOAD "edit-delete"
#define ICON_PLUGIN_RELOAD "view-refresh"
#endif
#if !HAVE_GTK3
#define ICON_PLUGIN_LOAD GTK_STOCK_REVERT_TO_SAVED
#define ICON_PLUGIN_UNLOAD GTK_STOCK_DELETE
#define ICON_PLUGIN_RELOAD GTK_STOCK_REFRESH
#endif
#if HAVE_GTK3
static GtkWidget *
plugingui_icon_button (GtkWidget *box, const char *label,
const char *icon_name, GCallback callback,
gpointer userdata)
{
GtkWidget *button;
GtkWidget *image;
button = gtk_button_new_with_mnemonic (label);
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
gtk_container_add (GTK_CONTAINER (box), button);
g_signal_connect (G_OBJECT (button), "clicked", callback, userdata);
gtk_widget_show (button);
return button;
}
#endif
static GtkWidget * static GtkWidget *
plugingui_treeview_new (GtkWidget *box) plugingui_treeview_new (GtkWidget *box)
@@ -120,21 +168,27 @@ fe_pluginlist_update (void)
return; return;
view = g_object_get_data (G_OBJECT (plugin_window), "view"); view = g_object_get_data (G_OBJECT (plugin_window), "view");
if (!GTK_IS_TREE_VIEW (view))
return;
store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
if (!GTK_IS_LIST_STORE (store))
return;
gtk_list_store_clear (store); gtk_list_store_clear (store);
list = plugin_list; list = plugin_list;
while (list) while (list)
{ {
pl = list->data; pl = list->data;
if (pl->version[0] != 0) if (pl && pl->version && pl->version[0] != 0)
{ {
gtk_list_store_append (store, &iter); gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, NAME_COLUMN, pl->name, gtk_list_store_set (store, &iter, NAME_COLUMN, plugingui_safe_string (pl->name),
VERSION_COLUMN, pl->version, VERSION_COLUMN, plugingui_safe_string (pl->version),
FILE_COLUMN, file_part (pl->filename), FILE_COLUMN, pl->filename ? file_part (pl->filename) : "",
DESC_COLUMN, pl->desc, DESC_COLUMN, plugingui_safe_string (pl->desc),
FILEPATH_COLUMN, pl->filename, -1); FILEPATH_COLUMN, plugingui_safe_string (pl->filename), -1);
} }
list = list->next; list = list->next;
} }
@@ -143,15 +197,36 @@ fe_pluginlist_update (void)
static void static void
plugingui_load_cb (session *sess, char *file) plugingui_load_cb (session *sess, char *file)
{ {
session *target_sess;
if (file) if (file)
{ {
char *buf; char *buf;
char *load_target;
if (strchr (file, ' ')) target_sess = is_session (sess) ? sess : current_sess;
buf = g_strdup_printf ("LOAD \"%s\"", file); if (!is_session (target_sess))
{
fe_message (_("No active session available for loading addons."), FE_MSG_ERROR);
return;
}
load_target = g_strdup (file);
#ifdef WIN32
/*
* The command parser is more reliable with forward slashes on Windows
* paths (especially when quoted), so normalize before issuing LOAD.
*/
g_strdelimit (load_target, "\\", '/');
#endif
if (strchr (load_target, ' '))
buf = g_strdup_printf ("LOAD \"%s\"", load_target);
else else
buf = g_strdup_printf ("LOAD %s", file); buf = g_strdup_printf ("LOAD %s", load_target);
handle_command (sess, buf, FALSE); handle_command (target_sess, buf, FALSE);
g_free (load_target);
g_free (buf); g_free (buf);
} }
} }
@@ -159,12 +234,15 @@ plugingui_load_cb (session *sess, char *file)
void void
plugingui_load (void) plugingui_load (void)
{ {
char *sub_dir = g_build_filename (get_xdir(), "addons", NULL); const char *xdir = get_xdir ();
char *sub_dir = NULL;
gtkutil_file_req (NULL, _("Select a Plugin or Script to load"), plugingui_load_cb, current_sess, if (xdir && xdir[0] != '\0')
sub_dir, "*."PLUGIN_SUFFIX";*.lua;*.pl;*.py;*.tcl;*.js", FRF_FILTERISINITIAL|FRF_EXTENSIONS); sub_dir = g_build_filename (xdir, "addons", NULL);
g_free (sub_dir); gtkutil_file_req (NULL, _("Select a Plugin or Script to load"), plugingui_load_cb, NULL,
sub_dir, "*."PLUGIN_SUFFIX";*.lua;*.pl;*.py;*.tcl;*.js", FRF_FILTERISINITIAL|FRF_EXTENSIONS);
g_free (sub_dir);
} }
static void static void
@@ -177,6 +255,7 @@ static void
plugingui_unload (GtkWidget * wid, gpointer unused) plugingui_unload (GtkWidget * wid, gpointer unused)
{ {
char *modname, *file; char *modname, *file;
session *target_sess;
GtkTreeView *view; GtkTreeView *view;
GtkTreeIter iter; GtkTreeIter iter;
@@ -184,6 +263,18 @@ plugingui_unload (GtkWidget * wid, gpointer unused)
if (!gtkutil_treeview_get_selected (view, &iter, NAME_COLUMN, &modname, if (!gtkutil_treeview_get_selected (view, &iter, NAME_COLUMN, &modname,
FILEPATH_COLUMN, &file, -1)) FILEPATH_COLUMN, &file, -1))
return; return;
if (!modname || !*modname)
{
g_free (modname);
g_free (file);
return;
}
if (!file || !*file)
{
g_free (modname);
g_free (file);
return;
}
if (g_str_has_suffix (file, "."PLUGIN_SUFFIX)) if (g_str_has_suffix (file, "."PLUGIN_SUFFIX))
{ {
@@ -194,11 +285,19 @@ plugingui_unload (GtkWidget * wid, gpointer unused)
{ {
char *buf; char *buf;
/* let python.so or perl.so handle it */ /* let python.so or perl.so handle it */
target_sess = plugingui_get_target_session ();
if (!target_sess)
{
g_free (modname);
g_free (file);
return;
}
if (strchr (file, ' ')) if (strchr (file, ' '))
buf = g_strdup_printf ("UNLOAD \"%s\"", file); buf = g_strdup_printf ("UNLOAD \"%s\"", file);
else else
buf = g_strdup_printf ("UNLOAD %s", file); buf = g_strdup_printf ("UNLOAD %s", file);
handle_command (current_sess, buf, FALSE); handle_command (target_sess, buf, FALSE);
g_free (buf); g_free (buf);
} }
@@ -210,16 +309,24 @@ static void
plugingui_reloadbutton_cb (GtkWidget *wid, GtkTreeView *view) plugingui_reloadbutton_cb (GtkWidget *wid, GtkTreeView *view)
{ {
char *file = plugingui_getfilename(view); char *file = plugingui_getfilename(view);
session *target_sess;
if (file) if (file)
{ {
char *buf; char *buf;
target_sess = plugingui_get_target_session ();
if (!target_sess)
{
g_free (file);
return;
}
if (strchr (file, ' ')) if (strchr (file, ' '))
buf = g_strdup_printf ("RELOAD \"%s\"", file); buf = g_strdup_printf ("RELOAD \"%s\"", file);
else else
buf = g_strdup_printf ("RELOAD %s", file); buf = g_strdup_printf ("RELOAD %s", file);
handle_command (current_sess, buf, FALSE); handle_command (target_sess, buf, FALSE);
g_free (buf); g_free (buf);
g_free (file); g_free (file);
} }
@@ -229,6 +336,7 @@ void
plugingui_open (void) plugingui_open (void)
{ {
GtkWidget *view; GtkWidget *view;
GtkWidget *view_scroll;
GtkWidget *vbox, *hbox; GtkWidget *vbox, *hbox;
char buf[128]; char buf[128];
@@ -244,22 +352,46 @@ plugingui_open (void)
gtkutil_destroy_on_esc (plugin_window); gtkutil_destroy_on_esc (plugin_window);
view = plugingui_treeview_new (vbox); view = plugingui_treeview_new (vbox);
view_scroll = gtk_widget_get_parent (view);
if (view_scroll)
{
gtk_box_set_child_packing (GTK_BOX (vbox), view_scroll, TRUE, TRUE, 0, GTK_PACK_START);
gtk_widget_set_hexpand (view_scroll, TRUE);
gtk_widget_set_vexpand (view_scroll, TRUE);
}
g_object_set_data (G_OBJECT (plugin_window), "view", view); g_object_set_data (G_OBJECT (plugin_window), "view", view);
#if HAVE_GTK3
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
hbox = gtk_hbutton_box_new (); hbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
gtk_box_pack_end (GTK_BOX (vbox), hbox, 0, 0, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, 0, 0, 0);
gtkutil_button (hbox, GTK_STOCK_REVERT_TO_SAVED, NULL, #if HAVE_GTK3
{
plugingui_icon_button (hbox, _("_Load..."), ICON_PLUGIN_LOAD,
G_CALLBACK (plugingui_loadbutton_cb), NULL);
plugingui_icon_button (hbox, _("_Unload"), ICON_PLUGIN_UNLOAD,
G_CALLBACK (plugingui_unload), NULL);
plugingui_icon_button (hbox, _("_Reload"), ICON_PLUGIN_RELOAD,
G_CALLBACK (plugingui_reloadbutton_cb), view);
}
#endif
#if !HAVE_GTK3
gtkutil_button (hbox, ICON_PLUGIN_LOAD, NULL,
plugingui_loadbutton_cb, NULL, _("_Load...")); plugingui_loadbutton_cb, NULL, _("_Load..."));
gtkutil_button (hbox, GTK_STOCK_DELETE, NULL, gtkutil_button (hbox, ICON_PLUGIN_UNLOAD, NULL,
plugingui_unload, NULL, _("_Unload")); plugingui_unload, NULL, _("_Unload"));
gtkutil_button (hbox, GTK_STOCK_REFRESH, NULL, gtkutil_button (hbox, ICON_PLUGIN_RELOAD, NULL,
plugingui_reloadbutton_cb, view, _("_Reload")); plugingui_reloadbutton_cb, view, _("_Reload"));
#endif
fe_pluginlist_update (); fe_pluginlist_update ();

View File

@@ -42,6 +42,15 @@
#include "xtext.h" #include "xtext.h"
#include "fkeys.h" #include "fkeys.h"
#if HAVE_GTK3
#define ICON_RAWLOG_CLEAR "edit-clear"
#define ICON_RAWLOG_SAVE_AS "document-save-as"
#endif
#if !HAVE_GTK3
#define ICON_RAWLOG_CLEAR GTK_STOCK_CLEAR
#define ICON_RAWLOG_SAVE_AS GTK_STOCK_SAVE_AS
#endif
static void static void
close_rawlog (GtkWidget *wid, server *serv) close_rawlog (GtkWidget *wid, server *serv)
{ {
@@ -119,7 +128,13 @@ open_rawlog (struct server *serv)
scrolledwindow = gtk_scrolled_window_new (NULL, NULL); scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN);
#if HAVE_GTK3
gtk_widget_set_hexpand (scrolledwindow, TRUE);
gtk_widget_set_vexpand (scrolledwindow, TRUE);
gtk_box_pack_start (GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0);
#elif !HAVE_GTK3
gtk_container_add (GTK_CONTAINER (vbox), scrolledwindow); gtk_container_add (GTK_CONTAINER (vbox), scrolledwindow);
#endif
palette_get_xtext_colors (xtext_palette, XTEXT_COLS); palette_get_xtext_colors (xtext_palette, XTEXT_COLS);
serv->gui->rawlog_textlist = gtk_xtext_new (xtext_palette, 0); serv->gui->rawlog_textlist = gtk_xtext_new (xtext_palette, 0);
@@ -127,14 +142,19 @@ open_rawlog (struct server *serv)
gtk_xtext_set_font (GTK_XTEXT (serv->gui->rawlog_textlist), prefs.hex_text_font); gtk_xtext_set_font (GTK_XTEXT (serv->gui->rawlog_textlist), prefs.hex_text_font);
GTK_XTEXT (serv->gui->rawlog_textlist)->ignore_hidden = 1; GTK_XTEXT (serv->gui->rawlog_textlist)->ignore_hidden = 1;
#if HAVE_GTK3
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
bbox = gtk_hbutton_box_new (); bbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 4); gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 4);
gtkutil_button (bbox, GTK_STOCK_CLEAR, NULL, rawlog_clearbutton, gtkutil_button (bbox, ICON_RAWLOG_CLEAR, NULL, rawlog_clearbutton,
serv, _("Clear Raw Log")); serv, _("Clear Raw Log"));
gtkutil_button (bbox, GTK_STOCK_SAVE_AS, NULL, rawlog_savebutton, gtkutil_button (bbox, ICON_RAWLOG_SAVE_AS, NULL, rawlog_savebutton,
serv, _("Save As...")); serv, _("Save As..."));
/* Copy selection to clipboard when Ctrl+Shift+C is pressed AND text auto-copy is disabled */ /* Copy selection to clipboard when Ctrl+Shift+C is pressed AND text auto-copy is disabled */

View File

@@ -39,6 +39,21 @@
#define SERVLIST_X_PADDING 4 /* horizontal paddig in the network editor */ #define SERVLIST_X_PADDING 4 /* horizontal paddig in the network editor */
#define SERVLIST_Y_PADDING 0 /* vertical padding in the network editor */ #define SERVLIST_Y_PADDING 0 /* vertical padding in the network editor */
#if HAVE_GTK3
#define ICON_SERVLIST_CONNECT "network-connect"
#define ICON_SERVLIST_ADD "list-add"
#define ICON_SERVLIST_REMOVE "list-remove"
#define ICON_SERVLIST_CLOSE "window-close"
#define ICON_SERVLIST_ERROR "dialog-error"
#endif
#if !HAVE_GTK3
#define ICON_SERVLIST_CONNECT GTK_STOCK_CONNECT
#define ICON_SERVLIST_ADD GTK_STOCK_ADD
#define ICON_SERVLIST_REMOVE GTK_STOCK_REMOVE
#define ICON_SERVLIST_CLOSE GTK_STOCK_CLOSE
#define ICON_SERVLIST_ERROR GTK_STOCK_DIALOG_ERROR
#endif
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
# define DEFAULT_SERVER "newserver/6697" # define DEFAULT_SERVER "newserver/6697"
#else #else
@@ -92,6 +107,22 @@ static session *servlist_sess;
static void servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data); static void servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data);
static GtkWidget *servlist_open_edit (GtkWidget *parent, ircnet *net); static GtkWidget *servlist_open_edit (GtkWidget *parent, ircnet *net);
#if HAVE_GTK3
static GtkWidget *
servlist_icon_button_new (const char *label, const char *icon_name)
{
GtkWidget *button;
GtkWidget *image;
button = gtk_button_new_with_mnemonic (label);
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_button_set_always_show_image (GTK_BUTTON (button), TRUE);
return button;
}
#endif
static const char *pages[]= static const char *pages[]=
{ {
@@ -1251,6 +1282,73 @@ servlist_check_cb (GtkWidget *but, gpointer num_p)
} }
} }
typedef enum
{
SERVLIST_ALIGN_START,
SERVLIST_ALIGN_CENTER,
SERVLIST_ALIGN_FILL
} servlist_align;
#if HAVE_GTK3
static GtkAlign
servlist_align_to_gtk (servlist_align align)
{
switch (align)
{
case SERVLIST_ALIGN_FILL:
return GTK_ALIGN_FILL;
case SERVLIST_ALIGN_CENTER:
return GTK_ALIGN_CENTER;
case SERVLIST_ALIGN_START:
default:
return GTK_ALIGN_START;
}
}
#endif
static void
servlist_table_attach (GtkWidget *table, GtkWidget *child,
guint left_attach, guint right_attach,
guint top_attach, guint bottom_attach,
gboolean hexpand, gboolean vexpand,
servlist_align halign, servlist_align valign,
guint xpad, guint ypad)
{
#if HAVE_GTK3
gtk_widget_set_hexpand (child, hexpand);
gtk_widget_set_vexpand (child, vexpand);
gtk_widget_set_halign (child, servlist_align_to_gtk (halign));
gtk_widget_set_valign (child, servlist_align_to_gtk (valign));
gtk_widget_set_margin_start (child, xpad);
gtk_widget_set_margin_end (child, xpad);
gtk_widget_set_margin_top (child, ypad);
gtk_widget_set_margin_bottom (child, ypad);
gtk_grid_attach (GTK_GRID (table), child, left_attach, top_attach,
right_attach - left_attach, bottom_attach - top_attach);
#else
GtkAttachOptions xoptions = 0;
GtkAttachOptions yoptions = 0;
if (hexpand)
xoptions |= GTK_EXPAND;
else
xoptions |= GTK_SHRINK;
if (halign == SERVLIST_ALIGN_FILL)
xoptions |= GTK_FILL;
if (vexpand)
yoptions |= GTK_EXPAND;
else
yoptions |= GTK_SHRINK;
if (valign == SERVLIST_ALIGN_FILL)
yoptions |= GTK_FILL;
gtk_table_attach (GTK_TABLE (table), child, left_attach, right_attach,
top_attach, bottom_attach, xoptions, yoptions,
xpad, ypad);
#endif
}
static GtkWidget * static GtkWidget *
servlist_create_check (int num, int state, GtkWidget *table, int row, int col, char *labeltext) servlist_create_check (int num, int state, GtkWidget *table, int row, int col, char *labeltext)
{ {
@@ -1260,7 +1358,10 @@ servlist_create_check (int num, int state, GtkWidget *table, int row, int col, c
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (but), state); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (but), state);
g_signal_connect (G_OBJECT (but), "toggled", g_signal_connect (G_OBJECT (but), "toggled",
G_CALLBACK (servlist_check_cb), GINT_TO_POINTER (num)); G_CALLBACK (servlist_check_cb), GINT_TO_POINTER (num));
gtk_table_attach (GTK_TABLE (table), but, col, col+2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); servlist_table_attach (table, but, col, col + 2, row, row + 1,
TRUE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
gtk_widget_show (but); gtk_widget_show (but);
return but; return but;
@@ -1276,8 +1377,16 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row,
if (label_ret) if (label_ret)
*label_ret = label; *label_ret = label;
gtk_widget_show (label); gtk_widget_show (label);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, GTK_FILL, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); servlist_table_attach (table, label, 0, 1, row, row + 1,
FALSE, FALSE,
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
#if HAVE_GTK3
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#endif
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_widget_set_tooltip_text (entry, tip); gtk_widget_set_tooltip_text (entry, tip);
@@ -1285,7 +1394,10 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row,
gtk_entry_set_text (GTK_ENTRY (entry), def ? def : ""); gtk_entry_set_text (GTK_ENTRY (entry), def ? def : "");
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, SERVLIST_X_PADDING, SERVLIST_Y_PADDING); servlist_table_attach (table, entry, 1, 2, row, row + 1,
TRUE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
return entry; return entry;
} }
@@ -1563,14 +1675,24 @@ servlist_username_changed_cb (GtkEntry *entry, gpointer userdata)
if (gtk_entry_get_text (entry)[0] == 0) if (gtk_entry_get_text (entry)[0] == 0)
{ {
#if HAVE_GTK3
gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, ICON_SERVLIST_ERROR);
#endif
#if !HAVE_GTK3
gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_ERROR); gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_ERROR);
#endif
gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY,
_("User name cannot be left blank.")); _("User name cannot be left blank."));
gtk_widget_set_sensitive (connect_btn, FALSE); gtk_widget_set_sensitive (connect_btn, FALSE);
} }
else else
{ {
#if HAVE_GTK3
gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
#endif
#if !HAVE_GTK3
gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, NULL); gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
#endif
gtk_widget_set_sensitive (connect_btn, TRUE); gtk_widget_set_sensitive (connect_btn, TRUE);
} }
} }
@@ -1585,22 +1707,38 @@ servlist_nick_changed_cb (GtkEntry *entry, gpointer userdata)
if (!nick1[0] || !nick2[0]) if (!nick1[0] || !nick2[0])
{ {
entry = GTK_ENTRY(!nick1[0] ? entry_nick1 : entry_nick2); entry = GTK_ENTRY(!nick1[0] ? entry_nick1 : entry_nick2);
#if HAVE_GTK3
gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, ICON_SERVLIST_ERROR);
#endif
#if !HAVE_GTK3
gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_ERROR); gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_ERROR);
#endif
gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY,
_("You cannot have an empty nick name.")); _("You cannot have an empty nick name."));
gtk_widget_set_sensitive (connect_btn, FALSE); gtk_widget_set_sensitive (connect_btn, FALSE);
} }
else if (!rfc_casecmp (nick1, nick2)) else if (!rfc_casecmp (nick1, nick2))
{ {
#if HAVE_GTK3
gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, ICON_SERVLIST_ERROR);
#endif
#if !HAVE_GTK3
gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_ERROR); gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_ERROR);
#endif
gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY,
_("You must have two unique nick names.")); _("You must have two unique nick names."));
gtk_widget_set_sensitive (connect_btn, FALSE); gtk_widget_set_sensitive (connect_btn, FALSE);
} }
else else
{ {
#if HAVE_GTK3
gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_nick1), GTK_ENTRY_ICON_SECONDARY, NULL);
gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_nick2), GTK_ENTRY_ICON_SECONDARY, NULL);
#endif
#if !HAVE_GTK3
gtk_entry_set_icon_from_stock (GTK_ENTRY(entry_nick1), GTK_ENTRY_ICON_SECONDARY, NULL); gtk_entry_set_icon_from_stock (GTK_ENTRY(entry_nick1), GTK_ENTRY_ICON_SECONDARY, NULL);
gtk_entry_set_icon_from_stock (GTK_ENTRY(entry_nick2), GTK_ENTRY_ICON_SECONDARY, NULL); gtk_entry_set_icon_from_stock (GTK_ENTRY(entry_nick2), GTK_ENTRY_ICON_SECONDARY, NULL);
#endif
gtk_widget_set_sensitive (connect_btn, TRUE); gtk_widget_set_sensitive (connect_btn, TRUE);
} }
} }
@@ -1680,7 +1818,12 @@ bold_label (char *text)
g_snprintf (buf, sizeof (buf), "<b>%s</b>", text); g_snprintf (buf, sizeof (buf), "<b>%s</b>", text);
label = gtk_label_new (buf); label = gtk_label_new (buf);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
#if HAVE_GTK3
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#endif
gtk_widget_show (label); gtk_widget_show (label);
return label; return label;
@@ -1727,12 +1870,12 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
gtk_window_set_type_hint (GTK_WINDOW (editwindow), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_type_hint (GTK_WINDOW (editwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
gtk_window_set_role (GTK_WINDOW (editwindow), "editserv"); gtk_window_set_role (GTK_WINDOW (editwindow), "editserv");
vbox5 = gtk_vbox_new (FALSE, 0); vbox5 = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
gtk_container_add (GTK_CONTAINER (editwindow), vbox5); gtk_container_add (GTK_CONTAINER (editwindow), vbox5);
/* Tabs and buttons */ /* Tabs and buttons */
hbox1 = gtk_hbox_new (FALSE, 0); hbox1 = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox5), hbox1, TRUE, TRUE, 4); gtk_box_pack_start (GTK_BOX (vbox5), hbox1, TRUE, TRUE, 4);
scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
@@ -1845,18 +1988,32 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
/* Button Box */ /* Button Box */
#if HAVE_GTK3
vbuttonbox1 = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
#elif !HAVE_GTK3
vbuttonbox1 = gtk_vbutton_box_new (); vbuttonbox1 = gtk_vbutton_box_new ();
#endif
gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3); gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3);
gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START); gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
gtk_box_pack_start (GTK_BOX (hbox1), vbuttonbox1, FALSE, FALSE, 3); gtk_box_pack_start (GTK_BOX (hbox1), vbuttonbox1, FALSE, FALSE, 3);
buttonadd = gtk_button_new_from_stock ("gtk-add"); #if HAVE_GTK3
buttonadd = servlist_icon_button_new (_("_Add"), ICON_SERVLIST_ADD);
#endif
#if !HAVE_GTK3
buttonadd = gtk_button_new_from_stock (GTK_STOCK_ADD);
#endif
g_signal_connect (G_OBJECT (buttonadd), "clicked", g_signal_connect (G_OBJECT (buttonadd), "clicked",
G_CALLBACK (servlist_addbutton_cb), notebook); G_CALLBACK (servlist_addbutton_cb), notebook);
gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonadd); gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonadd);
gtk_widget_set_can_default (buttonadd, TRUE); gtk_widget_set_can_default (buttonadd, TRUE);
buttonremove = gtk_button_new_from_stock ("gtk-remove"); #if HAVE_GTK3
buttonremove = servlist_icon_button_new (_("_Remove"), ICON_SERVLIST_REMOVE);
#endif
#if !HAVE_GTK3
buttonremove = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
#endif
g_signal_connect (G_OBJECT (buttonremove), "clicked", g_signal_connect (G_OBJECT (buttonremove), "clicked",
G_CALLBACK (servlist_deletebutton_cb), notebook); G_CALLBACK (servlist_deletebutton_cb), notebook);
gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonremove); gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonremove);
@@ -1870,10 +2027,15 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
/* Checkboxes and entries */ /* Checkboxes and entries */
table3 = gtk_table_new (13, 2, FALSE); table3 = gtkutil_grid_new (13, 2, FALSE);
gtk_box_pack_start (GTK_BOX (vbox5), table3, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox5), table3, FALSE, FALSE, 0);
#if HAVE_GTK3
gtk_grid_set_row_spacing (GTK_GRID (table3), 2);
gtk_grid_set_column_spacing (GTK_GRID (table3), 8);
#else
gtk_table_set_row_spacings (GTK_TABLE (table3), 2); gtk_table_set_row_spacings (GTK_TABLE (table3), 2);
gtk_table_set_col_spacings (GTK_TABLE (table3), 8); gtk_table_set_col_spacings (GTK_TABLE (table3), 8);
#endif
check = servlist_create_check (0, !(net->flags & FLAG_CYCLE), table3, 0, 0, _("Connect to selected server only")); check = servlist_create_check (0, !(net->flags & FLAG_CYCLE), table3, 0, 0, _("Connect to selected server only"));
gtk_widget_set_tooltip_text (check, _("Don't cycle through all the servers when the connection fails.")); gtk_widget_set_tooltip_text (check, _("Don't cycle through all the servers when the connection fails."));
@@ -1895,10 +2057,21 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
edit_entry_user = servlist_create_entry (table3, _("_User name:"), 9, net->user, &edit_label_user, 0); edit_entry_user = servlist_create_entry (table3, _("_User name:"), 9, net->user, &edit_label_user, 0);
label_logintype = gtk_label_new (_("Login method:")); label_logintype = gtk_label_new (_("Login method:"));
gtk_table_attach (GTK_TABLE (table3), label_logintype, 0, 1, 10, 11, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), SERVLIST_X_PADDING, SERVLIST_Y_PADDING); servlist_table_attach (table3, label_logintype, 0, 1, 10, 11,
FALSE, FALSE,
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
#if HAVE_GTK3
gtk_widget_set_halign (label_logintype, GTK_ALIGN_START);
gtk_widget_set_valign (label_logintype, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5);
#endif
combobox_logintypes = servlist_create_logintypecombo (notebook); combobox_logintypes = servlist_create_logintypecombo (notebook);
gtk_table_attach (GTK_TABLE (table3), combobox_logintypes, 1, 2, 10, 11, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 4, 2); servlist_table_attach (table3, combobox_logintypes, 1, 2, 10, 11,
FALSE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_FILL,
4, 2);
edit_entry_pass = servlist_create_entry (table3, _("Password:"), 11, net->pass, 0, _("Password used for login. If in doubt, leave blank.")); edit_entry_pass = servlist_create_entry (table3, _("Password:"), 11, net->pass, 0, _("Password used for login. If in doubt, leave blank."));
gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE); gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE);
@@ -1906,21 +2079,46 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
gtk_widget_set_sensitive (edit_entry_pass, FALSE); gtk_widget_set_sensitive (edit_entry_pass, FALSE);
label34 = gtk_label_new (_("Character set:")); label34 = gtk_label_new (_("Character set:"));
gtk_table_attach (GTK_TABLE (table3), label34, 0, 1, 12, 13, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), SERVLIST_X_PADDING, SERVLIST_Y_PADDING); servlist_table_attach (table3, label34, 0, 1, 12, 13,
FALSE, FALSE,
SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
SERVLIST_X_PADDING, SERVLIST_Y_PADDING);
#if HAVE_GTK3
gtk_widget_set_halign (label34, GTK_ALIGN_START);
gtk_widget_set_valign (label34, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5);
#endif
comboboxentry_charset = servlist_create_charsetcombo (); comboboxentry_charset = servlist_create_charsetcombo ();
gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 1, 2, 12, 13, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 4, 2); servlist_table_attach (table3, comboboxentry_charset, 1, 2, 12, 13,
FALSE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_FILL,
4, 2);
/* Rule and Close button */ /* Rule and Close button */
#if HAVE_GTK3
hseparator2 = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
#elif !HAVE_GTK3
hseparator2 = gtk_hseparator_new (); hseparator2 = gtk_hseparator_new ();
#endif
gtk_box_pack_start (GTK_BOX (vbox5), hseparator2, FALSE, FALSE, 8); gtk_box_pack_start (GTK_BOX (vbox5), hseparator2, FALSE, FALSE, 8);
hbuttonbox4 = gtk_hbutton_box_new (); #if HAVE_GTK3
gtk_box_pack_start (GTK_BOX (vbox5), hbuttonbox4, FALSE, FALSE, 0); hbuttonbox4 = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox4), GTK_BUTTONBOX_END); gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox4), GTK_BUTTONBOX_END);
#elif !HAVE_GTK3
hbuttonbox4 = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox4), GTK_BUTTONBOX_END);
#endif
gtk_box_pack_start (GTK_BOX (vbox5), hbuttonbox4, FALSE, FALSE, 0);
button10 = gtk_button_new_from_stock ("gtk-close"); #if HAVE_GTK3
button10 = servlist_icon_button_new (_("_Close"), ICON_SERVLIST_CLOSE);
#endif
#if !HAVE_GTK3
button10 = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
#endif
g_signal_connect (G_OBJECT (button10), "clicked", g_signal_connect (G_OBJECT (button10), "clicked",
G_CALLBACK (servlist_edit_close_cb), 0); G_CALLBACK (servlist_edit_close_cb), 0);
gtk_container_add (GTK_CONTAINER (hbuttonbox4), button10); gtk_container_add (GTK_CONTAINER (hbuttonbox4), button10);
@@ -1994,82 +2192,115 @@ servlist_open_networks (void)
if (current_sess) if (current_sess)
gtk_window_set_transient_for (GTK_WINDOW (servlist), GTK_WINDOW (current_sess->gui->window)); gtk_window_set_transient_for (GTK_WINDOW (servlist), GTK_WINDOW (current_sess->gui->window));
vbox1 = gtk_vbox_new (FALSE, 0); vbox1 = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
gtk_widget_show (vbox1); gtk_widget_show (vbox1);
gtk_container_add (GTK_CONTAINER (servlist), vbox1); gtk_container_add (GTK_CONTAINER (servlist), vbox1);
label2 = bold_label (_("User Information")); label2 = bold_label (_("User Information"));
gtk_box_pack_start (GTK_BOX (vbox1), label2, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox1), label2, FALSE, FALSE, 0);
table1 = gtk_table_new (5, 2, FALSE); table1 = gtkutil_grid_new (5, 2, FALSE);
gtk_widget_show (table1); gtk_widget_show (table1);
gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (table1), 8); gtk_container_set_border_width (GTK_CONTAINER (table1), 8);
#if HAVE_GTK3
gtk_grid_set_row_spacing (GTK_GRID (table1), 2);
gtk_grid_set_column_spacing (GTK_GRID (table1), 4);
#else
gtk_table_set_row_spacings (GTK_TABLE (table1), 2); gtk_table_set_row_spacings (GTK_TABLE (table1), 2);
gtk_table_set_col_spacings (GTK_TABLE (table1), 4); gtk_table_set_col_spacings (GTK_TABLE (table1), 4);
#endif
label3 = gtk_label_new_with_mnemonic (_("_Nick name:")); label3 = gtk_label_new_with_mnemonic (_("_Nick name:"));
gtk_widget_show (label3); gtk_widget_show (label3);
gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 0, 1, servlist_table_attach (table1, label3, 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL), FALSE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
0, 0);
#if HAVE_GTK3
gtk_widget_set_halign (label3, GTK_ALIGN_START);
gtk_widget_set_valign (label3, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
#endif
label4 = gtk_label_new (_("Second choice:")); label4 = gtk_label_new (_("Second choice:"));
gtk_widget_show (label4); gtk_widget_show (label4);
gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 1, 2, servlist_table_attach (table1, label4, 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL), FALSE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
0, 0);
#if HAVE_GTK3
gtk_widget_set_halign (label4, GTK_ALIGN_START);
gtk_widget_set_valign (label4, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5);
#endif
label5 = gtk_label_new (_("Third choice:")); label5 = gtk_label_new (_("Third choice:"));
gtk_widget_show (label5); gtk_widget_show (label5);
gtk_table_attach (GTK_TABLE (table1), label5, 0, 1, 2, 3, servlist_table_attach (table1, label5, 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL), FALSE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
0, 0);
#if HAVE_GTK3
gtk_widget_set_halign (label5, GTK_ALIGN_START);
gtk_widget_set_valign (label5, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);
#endif
label6 = gtk_label_new_with_mnemonic (_("_User name:")); label6 = gtk_label_new_with_mnemonic (_("_User name:"));
gtk_widget_show (label6); gtk_widget_show (label6);
gtk_table_attach (GTK_TABLE (table1), label6, 0, 1, 3, 4, servlist_table_attach (table1, label6, 0, 1, 3, 4,
(GtkAttachOptions) (GTK_FILL), FALSE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_START, SERVLIST_ALIGN_CENTER,
0, 0);
#if HAVE_GTK3
gtk_widget_set_halign (label6, GTK_ALIGN_START);
gtk_widget_set_valign (label6, GTK_ALIGN_CENTER);
#elif !HAVE_GTK3
gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5); gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
#endif
/* label7 = gtk_label_new_with_mnemonic (_("Rea_l name:")); /* label7 = gtk_label_new_with_mnemonic (_("Rea_l name:"));
gtk_widget_show (label7); gtk_widget_show (label7);
gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 4, 5, gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 4, 5,
(GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0); (GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);*/ */
entry_nick1 = entry1 = gtk_entry_new (); entry_nick1 = entry1 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry1), prefs.hex_irc_nick1); gtk_entry_set_text (GTK_ENTRY (entry1), prefs.hex_irc_nick1);
gtk_widget_show (entry1); gtk_widget_show (entry1);
gtk_table_attach (GTK_TABLE (table1), entry1, 1, 2, 0, 1, servlist_table_attach (table1, entry1, 1, 2, 0, 1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), TRUE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
entry_nick2 = entry2 = gtk_entry_new (); entry_nick2 = entry2 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry2), prefs.hex_irc_nick2); gtk_entry_set_text (GTK_ENTRY (entry2), prefs.hex_irc_nick2);
gtk_widget_show (entry2); gtk_widget_show (entry2);
gtk_table_attach (GTK_TABLE (table1), entry2, 1, 2, 1, 2, servlist_table_attach (table1, entry2, 1, 2, 1, 2,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), TRUE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
entry_nick3 = entry3 = gtk_entry_new (); entry_nick3 = entry3 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry3), prefs.hex_irc_nick3); gtk_entry_set_text (GTK_ENTRY (entry3), prefs.hex_irc_nick3);
gtk_widget_show (entry3); gtk_widget_show (entry3);
gtk_table_attach (GTK_TABLE (table1), entry3, 1, 2, 2, 3, servlist_table_attach (table1, entry3, 1, 2, 2, 3,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), TRUE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
entry_guser = entry4 = gtk_entry_new (); entry_guser = entry4 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry4), prefs.hex_irc_user_name); gtk_entry_set_text (GTK_ENTRY (entry4), prefs.hex_irc_user_name);
gtk_widget_show (entry4); gtk_widget_show (entry4);
gtk_table_attach (GTK_TABLE (table1), entry4, 1, 2, 3, 4, servlist_table_attach (table1, entry4, 1, 2, 3, 4,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), TRUE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
/* entry_greal = entry5 = gtk_entry_new (); /* entry_greal = entry5 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry5), prefs.hex_irc_real_name); gtk_entry_set_text (GTK_ENTRY (entry5), prefs.hex_irc_real_name);
@@ -2078,25 +2309,31 @@ servlist_open_networks (void)
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0); */ (GtkAttachOptions) (0), 0, 0); */
vbox2 = gtk_vbox_new (FALSE, 0); vbox2 = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
gtk_widget_show (vbox2); gtk_widget_show (vbox2);
gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0);
label1 = bold_label (_("Networks")); label1 = bold_label (_("Networks"));
gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
table4 = gtk_table_new (2, 2, FALSE); table4 = gtkutil_grid_new (2, 2, FALSE);
gtk_widget_show (table4); gtk_widget_show (table4);
gtk_box_pack_start (GTK_BOX (vbox2), table4, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox2), table4, TRUE, TRUE, 0);
gtk_container_set_border_width (GTK_CONTAINER (table4), 8); gtk_container_set_border_width (GTK_CONTAINER (table4), 8);
#if HAVE_GTK3
gtk_grid_set_row_spacing (GTK_GRID (table4), 2);
gtk_grid_set_column_spacing (GTK_GRID (table4), 3);
#else
gtk_table_set_row_spacings (GTK_TABLE (table4), 2); gtk_table_set_row_spacings (GTK_TABLE (table4), 2);
gtk_table_set_col_spacings (GTK_TABLE (table4), 3); gtk_table_set_col_spacings (GTK_TABLE (table4), 3);
#endif
scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL); scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolledwindow3); gtk_widget_show (scrolledwindow3);
gtk_table_attach (GTK_TABLE (table4), scrolledwindow3, 0, 1, 0, 1, servlist_table_attach (table4, scrolledwindow3, 0, 1, 0, 1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), TRUE, TRUE,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_FILL,
0, 0);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3),
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow3), gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow3),
@@ -2123,10 +2360,11 @@ servlist_open_networks (void)
"weight", 2, "weight", 2,
NULL); NULL);
hbox = gtk_hbox_new (0, FALSE); hbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
gtk_table_attach (GTK_TABLE (table4), hbox, 0, 2, 1, 2, servlist_table_attach (table4, hbox, 0, 2, 1, 2,
(GtkAttachOptions) (GTK_FILL), FALSE, FALSE,
(GtkAttachOptions) (0), 0, 0); SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
gtk_widget_show (hbox); gtk_widget_show (hbox);
checkbutton_skip = checkbutton_skip =
@@ -2147,22 +2385,37 @@ servlist_open_networks (void)
G_CALLBACK (fav_servlist), 0); G_CALLBACK (fav_servlist), 0);
gtk_widget_show (checkbutton_fav); gtk_widget_show (checkbutton_fav);
#if HAVE_GTK3
vbuttonbox2 = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
#elif !HAVE_GTK3
vbuttonbox2 = gtk_vbutton_box_new (); vbuttonbox2 = gtk_vbutton_box_new ();
#endif
gtk_box_set_spacing (GTK_BOX (vbuttonbox2), 3); gtk_box_set_spacing (GTK_BOX (vbuttonbox2), 3);
gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox2), GTK_BUTTONBOX_START); gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox2), GTK_BUTTONBOX_START);
gtk_widget_show (vbuttonbox2); gtk_widget_show (vbuttonbox2);
gtk_table_attach (GTK_TABLE (table4), vbuttonbox2, 1, 2, 0, 1, servlist_table_attach (table4, vbuttonbox2, 1, 2, 0, 1,
(GtkAttachOptions) (GTK_FILL), FALSE, FALSE,
(GtkAttachOptions) (GTK_FILL), 0, 0); SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_FILL,
0, 0);
button_add = gtk_button_new_from_stock ("gtk-add"); #if HAVE_GTK3
button_add = servlist_icon_button_new (_("_Add"), ICON_SERVLIST_ADD);
#endif
#if !HAVE_GTK3
button_add = gtk_button_new_from_stock (GTK_STOCK_ADD);
#endif
g_signal_connect (G_OBJECT (button_add), "clicked", g_signal_connect (G_OBJECT (button_add), "clicked",
G_CALLBACK (servlist_addnet_cb), networks_tree); G_CALLBACK (servlist_addnet_cb), networks_tree);
gtk_widget_show (button_add); gtk_widget_show (button_add);
gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_add); gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_add);
gtk_widget_set_can_default (button_add, TRUE); gtk_widget_set_can_default (button_add, TRUE);
button_remove = gtk_button_new_from_stock ("gtk-remove"); #if HAVE_GTK3
button_remove = servlist_icon_button_new (_("_Remove"), ICON_SERVLIST_REMOVE);
#endif
#if !HAVE_GTK3
button_remove = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
#endif
g_signal_connect (G_OBJECT (button_remove), "clicked", g_signal_connect (G_OBJECT (button_remove), "clicked",
G_CALLBACK (servlist_deletenet_cb), 0); G_CALLBACK (servlist_deletenet_cb), 0);
gtk_widget_show (button_remove); gtk_widget_show (button_remove);
@@ -2193,23 +2446,38 @@ servlist_open_networks (void)
gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_sort); gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_sort);
gtk_widget_set_can_default (button_sort, TRUE); gtk_widget_set_can_default (button_sort, TRUE);
#if HAVE_GTK3
hseparator1 = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
#elif !HAVE_GTK3
hseparator1 = gtk_hseparator_new (); hseparator1 = gtk_hseparator_new ();
#endif
gtk_widget_show (hseparator1); gtk_widget_show (hseparator1);
gtk_box_pack_start (GTK_BOX (vbox1), hseparator1, FALSE, TRUE, 4); gtk_box_pack_start (GTK_BOX (vbox1), hseparator1, FALSE, TRUE, 4);
#if HAVE_GTK3
hbuttonbox1 = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
hbuttonbox1 = gtk_hbutton_box_new (); hbuttonbox1 = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_SPREAD);
#endif
gtk_widget_show (hbuttonbox1); gtk_widget_show (hbuttonbox1);
gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, TRUE, 0);
gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox1), 8); gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox1), 8);
button_close = gtk_button_new_from_stock ("gtk-close"); #if HAVE_GTK3
button_close = servlist_icon_button_new (_("_Close"), ICON_SERVLIST_CLOSE);
#endif
#if !HAVE_GTK3
button_close = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
#endif
gtk_widget_show (button_close); gtk_widget_show (button_close);
g_signal_connect (G_OBJECT (button_close), "clicked", g_signal_connect (G_OBJECT (button_close), "clicked",
G_CALLBACK (servlist_close_cb), 0); G_CALLBACK (servlist_close_cb), 0);
gtk_container_add (GTK_CONTAINER (hbuttonbox1), button_close); gtk_container_add (GTK_CONTAINER (hbuttonbox1), button_close);
gtk_widget_set_can_default (button_close, TRUE); gtk_widget_set_can_default (button_close, TRUE);
button_connect = gtkutil_button (hbuttonbox1, GTK_STOCK_CONNECT, NULL, button_connect = gtkutil_button (hbuttonbox1, ICON_SERVLIST_CONNECT, NULL,
servlist_connect_cb, NULL, _("C_onnect")); servlist_connect_cb, NULL, _("C_onnect"));
gtk_widget_set_can_default (button_connect, TRUE); gtk_widget_set_can_default (button_connect, TRUE);

File diff suppressed because it is too large Load Diff

View File

@@ -49,6 +49,26 @@
#include "../common/zoitechatc.h" #include "../common/zoitechatc.h"
#include "palette.h" #include "palette.h"
#include "xtext.h" #include "xtext.h"
#include "gtkutil.h"
#ifndef HAVE_GTK3
#if GTK_MAJOR_VERSION >= 3
#define HAVE_GTK3 1
#else
#define HAVE_GTK3 0
#endif
#endif
#if HAVE_GTK3
#define ICON_ADD "list-add"
#define ICON_REMOVE "list-remove"
#define ICON_SPELL_CHECK "tools-check-spelling"
#endif
#if !HAVE_GTK3
#define ICON_ADD GTK_STOCK_ADD
#define ICON_REMOVE GTK_STOCK_REMOVE
#define ICON_SPELL_CHECK GTK_STOCK_SPELL_CHECK
#endif
/* /*
* Bunch of poop to make enchant into a runtime dependency rather than a * Bunch of poop to make enchant into a runtime dependency rather than a
@@ -95,11 +115,21 @@ struct _SexySpellEntryPriv
}; };
static void sexy_spell_entry_class_init(SexySpellEntryClass *klass); static void sexy_spell_entry_class_init(SexySpellEntryClass *klass);
#if HAVE_GTK3
static void sexy_spell_entry_editable_init (GtkEditableInterface *iface);
#endif
#if !HAVE_GTK3
static void sexy_spell_entry_editable_init (GtkEditableClass *iface); static void sexy_spell_entry_editable_init (GtkEditableClass *iface);
#endif
static void sexy_spell_entry_init(SexySpellEntry *entry); static void sexy_spell_entry_init(SexySpellEntry *entry);
static void sexy_spell_entry_finalize(GObject *obj); static void sexy_spell_entry_finalize(GObject *obj);
static void sexy_spell_entry_destroy(GObject *obj); static void sexy_spell_entry_destroy(GObject *obj);
#if HAVE_GTK3
static gboolean sexy_spell_entry_draw(GtkWidget *widget, cairo_t *cr);
#endif
#if !HAVE_GTK3
static gint sexy_spell_entry_expose(GtkWidget *widget, GdkEventExpose *event); static gint sexy_spell_entry_expose(GtkWidget *widget, GdkEventExpose *event);
#endif
static gint sexy_spell_entry_button_press(GtkWidget *widget, GdkEventButton *event); static gint sexy_spell_entry_button_press(GtkWidget *widget, GdkEventButton *event);
/* GtkEditable handlers */ /* GtkEditable handlers */
@@ -243,7 +273,12 @@ sexy_spell_entry_class_init(SexySpellEntryClass *klass)
object_class->dispose = sexy_spell_entry_destroy; object_class->dispose = sexy_spell_entry_destroy;
#if HAVE_GTK3
widget_class->draw = sexy_spell_entry_draw;
#endif
#if !HAVE_GTK3
widget_class->expose_event = sexy_spell_entry_expose; widget_class->expose_event = sexy_spell_entry_expose;
#endif
widget_class->button_press_event = sexy_spell_entry_button_press; widget_class->button_press_event = sexy_spell_entry_button_press;
/** /**
@@ -274,10 +309,19 @@ sexy_spell_entry_class_init(SexySpellEntryClass *klass)
} }
} }
#if HAVE_GTK3
static void
sexy_spell_entry_editable_init (GtkEditableInterface *iface)
{
}
#endif
#if !HAVE_GTK3
static void static void
sexy_spell_entry_editable_init (GtkEditableClass *iface) sexy_spell_entry_editable_init (GtkEditableClass *iface)
{ {
} }
#endif
static gint static gint
gtk_entry_find_position (GtkEntry *entry, gint x) gtk_entry_find_position (GtkEntry *entry, gint x)
@@ -290,15 +334,34 @@ gtk_entry_find_position (GtkEntry *entry, gint x)
gint pos; gint pos;
gboolean trailing; gboolean trailing;
#if HAVE_GTK3
{
gint layout_x;
gint layout_y;
gtk_entry_get_layout_offsets(entry, &layout_x, &layout_y);
x -= layout_x;
}
#endif
#if !HAVE_GTK3
x = x + entry->scroll_offset; x = x + entry->scroll_offset;
#endif
layout = gtk_entry_get_layout(entry); layout = gtk_entry_get_layout(entry);
text = pango_layout_get_text(layout); text = pango_layout_get_text(layout);
#if HAVE_GTK3
cursor_index = g_utf8_offset_to_pointer(
text,
gtk_editable_get_position(GTK_EDITABLE(entry))) - text;
#endif
#if !HAVE_GTK3
cursor_index = g_utf8_offset_to_pointer(text, entry->current_pos) - text; cursor_index = g_utf8_offset_to_pointer(text, entry->current_pos) - text;
#endif
line = pango_layout_get_lines(layout)->data; line = pango_layout_get_lines(layout)->data;
pango_layout_line_x_to_index(line, x * PANGO_SCALE, &index, &trailing); pango_layout_line_x_to_index(line, x * PANGO_SCALE, &index, &trailing);
#if !HAVE_GTK3
if (index >= cursor_index && entry->preedit_length) { if (index >= cursor_index && entry->preedit_length) {
if (index >= cursor_index + entry->preedit_length) { if (index >= cursor_index + entry->preedit_length) {
index -= entry->preedit_length; index -= entry->preedit_length;
@@ -307,6 +370,7 @@ gtk_entry_find_position (GtkEntry *entry, gint x)
trailing = FALSE; trailing = FALSE;
} }
} }
#endif
pos = g_utf8_pointer_to_offset (text, text + index); pos = g_utf8_pointer_to_offset (text, text + index);
pos += trailing; pos += trailing;
@@ -342,8 +406,12 @@ insert_underline_error (SexySpellEntry *entry, guint start, guint end)
{ {
PangoAttribute *ucolor; PangoAttribute *ucolor;
PangoAttribute *unline; PangoAttribute *unline;
guint16 red;
guint16 green;
guint16 blue;
ucolor = pango_attr_underline_color_new (colors[COL_SPELL].red, colors[COL_SPELL].green, colors[COL_SPELL].blue); palette_color_get_rgb16 (&colors[COL_SPELL], &red, &green, &blue);
ucolor = pango_attr_underline_color_new (red, green, blue);
unline = pango_attr_underline_new (PANGO_UNDERLINE_ERROR); unline = pango_attr_underline_new (PANGO_UNDERLINE_ERROR);
ucolor->start_index = start; ucolor->start_index = start;
@@ -406,22 +474,33 @@ insert_color (SexySpellEntry *entry, guint start, int fgcolor, int bgcolor)
PangoAttribute *fgattr; PangoAttribute *fgattr;
PangoAttribute *ulattr; PangoAttribute *ulattr;
PangoAttribute *bgattr; PangoAttribute *bgattr;
guint16 red;
guint16 green;
guint16 blue;
if (fgcolor < 0 || fgcolor > MAX_COL) if (fgcolor < 0 || fgcolor > MAX_COL)
{ {
fgattr = pango_attr_foreground_new (colors[COL_FG].red, colors[COL_FG].green, colors[COL_FG].blue); palette_color_get_rgb16 (&colors[COL_FG], &red, &green, &blue);
ulattr = pango_attr_underline_color_new (colors[COL_FG].red, colors[COL_FG].green, colors[COL_FG].blue); fgattr = pango_attr_foreground_new (red, green, blue);
ulattr = pango_attr_underline_color_new (red, green, blue);
} }
else else
{ {
fgattr = pango_attr_foreground_new (colors[fgcolor].red, colors[fgcolor].green, colors[fgcolor].blue); palette_color_get_rgb16 (&colors[fgcolor], &red, &green, &blue);
ulattr = pango_attr_underline_color_new (colors[fgcolor].red, colors[fgcolor].green, colors[fgcolor].blue); fgattr = pango_attr_foreground_new (red, green, blue);
ulattr = pango_attr_underline_color_new (red, green, blue);
} }
if (bgcolor < 0 || bgcolor > MAX_COL) if (bgcolor < 0 || bgcolor > MAX_COL)
bgattr = pango_attr_background_new (colors[COL_BG].red, colors[COL_BG].green, colors[COL_BG].blue); {
palette_color_get_rgb16 (&colors[COL_BG], &red, &green, &blue);
bgattr = pango_attr_background_new (red, green, blue);
}
else else
bgattr = pango_attr_background_new (colors[bgcolor].red, colors[bgcolor].green, colors[bgcolor].blue); {
palette_color_get_rgb16 (&colors[bgcolor], &red, &green, &blue);
bgattr = pango_attr_background_new (red, green, blue);
}
fgattr->start_index = start; fgattr->start_index = start;
fgattr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END; fgattr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END;
@@ -540,7 +619,36 @@ replace_word(GtkWidget *menuitem, SexySpellEntry *entry)
get_word_extents_from_position(entry, &start, &end, entry->priv->mark_character); get_word_extents_from_position(entry, &start, &end, entry->priv->mark_character);
oldword = gtk_editable_get_chars(GTK_EDITABLE(entry), start, end); oldword = gtk_editable_get_chars(GTK_EDITABLE(entry), start, end);
newword = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child (GTK_BIN(menuitem)))); newword = gtk_menu_item_get_label (GTK_MENU_ITEM (menuitem));
if (!newword)
{
/* GTK3 menu items may have a box child (icon + label). */
GtkWidget *child = gtk_bin_get_child (GTK_BIN (menuitem));
if (GTK_IS_LABEL (child))
{
newword = gtk_label_get_text (GTK_LABEL (child));
}
else if (GTK_IS_CONTAINER (child))
{
GList *kids, *l;
kids = gtk_container_get_children (GTK_CONTAINER (child));
for (l = kids; l; l = l->next)
{
if (GTK_IS_LABEL (l->data))
{
newword = gtk_label_get_text (GTK_LABEL (l->data));
break;
}
}
g_list_free (kids);
}
}
if (!newword)
{
g_free (oldword);
return;
}
cursor = gtk_editable_get_position(GTK_EDITABLE(entry)); cursor = gtk_editable_get_position(GTK_EDITABLE(entry));
/* is the cursor at the end? If so, restore it there */ /* is the cursor at the end? If so, restore it there */
@@ -613,6 +721,39 @@ build_suggestion_menu(SexySpellEntry *entry, GtkWidget *menu, struct EnchantDict
enchant_dict_free_suggestions(dict, suggestions); enchant_dict_free_suggestions(dict, suggestions);
} }
static GtkWidget *
sexy_spell_entry_icon_menu_item (const char *label, const char *stock_name)
{
GtkWidget *item;
#if HAVE_GTK3
const char *icon_name;
GtkWidget *box;
GtkWidget *image = NULL;
GtkWidget *label_widget;
icon_name = gtkutil_icon_name_from_stock (stock_name);
if (!icon_name)
icon_name = stock_name;
item = gtk_menu_item_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
if (icon_name)
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
label_widget = gtk_label_new_with_mnemonic (label);
if (image)
gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), label_widget, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (item), box);
#else
GtkWidget *image;
item = gtk_image_menu_item_new_with_label (label);
image = gtk_image_new_from_stock (stock_name, GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
#endif
return item;
}
static GtkWidget * static GtkWidget *
build_spelling_menu(SexySpellEntry *entry, const gchar *word) build_spelling_menu(SexySpellEntry *entry, const gchar *word)
{ {
@@ -667,11 +808,9 @@ build_spelling_menu(SexySpellEntry *entry, const gchar *word)
/* + Add to Dictionary */ /* + Add to Dictionary */
label = g_strdup_printf(_("Add \"%s\" to Dictionary"), word); label = g_strdup_printf(_("Add \"%s\" to Dictionary"), word);
mi = gtk_image_menu_item_new_with_label(label); mi = sexy_spell_entry_icon_menu_item (label, ICON_ADD);
g_free(label); g_free(label);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU));
if (g_slist_length(entry->priv->dict_list) == 1) { if (g_slist_length(entry->priv->dict_list) == 1) {
dict = (struct EnchantDict *) entry->priv->dict_list->data; dict = (struct EnchantDict *) entry->priv->dict_list->data;
g_object_set_data(G_OBJECT(mi), "enchant-dict", dict); g_object_set_data(G_OBJECT(mi), "enchant-dict", dict);
@@ -711,8 +850,7 @@ build_spelling_menu(SexySpellEntry *entry, const gchar *word)
gtk_menu_shell_append(GTK_MENU_SHELL(topmenu), mi); gtk_menu_shell_append(GTK_MENU_SHELL(topmenu), mi);
/* - Ignore All */ /* - Ignore All */
mi = gtk_image_menu_item_new_with_label(_("Ignore All")); mi = sexy_spell_entry_icon_menu_item (_("Ignore All"), ICON_REMOVE);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU));
g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(ignore_all), entry); g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(ignore_all), entry);
gtk_widget_show_all(mi); gtk_widget_show_all(mi);
gtk_menu_shell_append(GTK_MENU_SHELL(topmenu), mi); gtk_menu_shell_append(GTK_MENU_SHELL(topmenu), mi);
@@ -723,7 +861,7 @@ build_spelling_menu(SexySpellEntry *entry, const gchar *word)
static void static void
sexy_spell_entry_populate_popup(SexySpellEntry *entry, GtkMenu *menu, gpointer data) sexy_spell_entry_populate_popup(SexySpellEntry *entry, GtkMenu *menu, gpointer data)
{ {
GtkWidget *icon, *mi; GtkWidget *mi;
gint start, end; gint start, end;
gchar *word; gchar *word;
@@ -745,9 +883,7 @@ sexy_spell_entry_populate_popup(SexySpellEntry *entry, GtkMenu *menu, gpointer d
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), mi); gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), mi);
/* Above the separator, show the suggestions menu */ /* Above the separator, show the suggestions menu */
icon = gtk_image_new_from_stock(GTK_STOCK_SPELL_CHECK, GTK_ICON_SIZE_MENU); mi = sexy_spell_entry_icon_menu_item (_("Spelling Suggestions"), ICON_SPELL_CHECK);
mi = gtk_image_menu_item_new_with_label(_("Spelling Suggestions"));
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), icon);
word = gtk_editable_get_chars(GTK_EDITABLE(entry), start, end); word = gtk_editable_get_chars(GTK_EDITABLE(entry), start, end);
g_assert(word != NULL); g_assert(word != NULL);
@@ -1115,6 +1251,22 @@ sexy_spell_entry_recheck_all(SexySpellEntry *entry)
} }
} }
#if HAVE_GTK3
static gboolean
sexy_spell_entry_draw(GtkWidget *widget, cairo_t *cr)
{
SexySpellEntry *entry = SEXY_SPELL_ENTRY(widget);
GtkEntry *gtk_entry = GTK_ENTRY(widget);
PangoLayout *layout;
layout = gtk_entry_get_layout(gtk_entry);
pango_layout_set_attributes(layout, entry->priv->attr_list);
return GTK_WIDGET_CLASS(parent_class)->draw (widget, cr);
}
#endif
#if !HAVE_GTK3
static gint static gint
sexy_spell_entry_expose(GtkWidget *widget, GdkEventExpose *event) sexy_spell_entry_expose(GtkWidget *widget, GdkEventExpose *event)
{ {
@@ -1122,7 +1274,6 @@ sexy_spell_entry_expose(GtkWidget *widget, GdkEventExpose *event)
GtkEntry *gtk_entry = GTK_ENTRY(widget); GtkEntry *gtk_entry = GTK_ENTRY(widget);
PangoLayout *layout; PangoLayout *layout;
layout = gtk_entry_get_layout(gtk_entry); layout = gtk_entry_get_layout(gtk_entry);
if (gtk_entry->preedit_length == 0) if (gtk_entry->preedit_length == 0)
{ {
@@ -1135,6 +1286,7 @@ sexy_spell_entry_expose(GtkWidget *widget, GdkEventExpose *event)
return GTK_WIDGET_CLASS(parent_class)->expose_event (widget, event); return GTK_WIDGET_CLASS(parent_class)->expose_event (widget, event);
} }
#endif
static gint static gint
sexy_spell_entry_button_press(GtkWidget *widget, GdkEventButton *event) sexy_spell_entry_button_press(GtkWidget *widget, GdkEventButton *event)

View File

@@ -18,11 +18,14 @@
#ifndef _SEXY_SPELL_ENTRY_H_ #ifndef _SEXY_SPELL_ENTRY_H_
#define _SEXY_SPELL_ENTRY_H_ #define _SEXY_SPELL_ENTRY_H_
#include <gtk/gtk.h>
G_BEGIN_DECLS
typedef struct _SexySpellEntry SexySpellEntry; typedef struct _SexySpellEntry SexySpellEntry;
typedef struct _SexySpellEntryClass SexySpellEntryClass; typedef struct _SexySpellEntryClass SexySpellEntryClass;
typedef struct _SexySpellEntryPriv SexySpellEntryPriv;
#include <gtk/gtk.h> GType sexy_spell_entry_get_type(void);
#define SEXY_TYPE_SPELL_ENTRY (sexy_spell_entry_get_type()) #define SEXY_TYPE_SPELL_ENTRY (sexy_spell_entry_get_type())
#define SEXY_SPELL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SEXY_TYPE_SPELL_ENTRY, SexySpellEntry)) #define SEXY_SPELL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SEXY_TYPE_SPELL_ENTRY, SexySpellEntry))
@@ -31,6 +34,8 @@ typedef struct _SexySpellEntryPriv SexySpellEntryPriv;
#define SEXY_IS_SPELL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SEXY_TYPE_SPELL_ENTRY)) #define SEXY_IS_SPELL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SEXY_TYPE_SPELL_ENTRY))
#define SEXY_SPELL_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SEXY_TYPE_SPELL_ENTRY, SexySpellEntryClass)) #define SEXY_SPELL_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SEXY_TYPE_SPELL_ENTRY, SexySpellEntryClass))
typedef struct _SexySpellEntryPriv SexySpellEntryPriv;
#define SEXY_SPELL_ERROR (sexy_spell_error_quark()) #define SEXY_SPELL_ERROR (sexy_spell_error_quark())
typedef enum { typedef enum {
@@ -39,7 +44,11 @@ typedef enum {
struct _SexySpellEntry struct _SexySpellEntry
{ {
#if HAVE_GTK3
GtkEntry parent_instance;
#else
GtkEntry parent_object; GtkEntry parent_object;
#endif
SexySpellEntryPriv *priv; SexySpellEntryPriv *priv;
@@ -62,9 +71,6 @@ struct _SexySpellEntryClass
void (*gtk_reserved4)(void); void (*gtk_reserved4)(void);
}; };
G_BEGIN_DECLS
GType sexy_spell_entry_get_type(void);
GtkWidget *sexy_spell_entry_new(void); GtkWidget *sexy_spell_entry_new(void);
GQuark sexy_spell_error_quark(void); GQuark sexy_spell_error_quark(void);

View File

@@ -38,6 +38,17 @@
#include "palette.h" #include "palette.h"
#include "textgui.h" #include "textgui.h"
#if HAVE_GTK3
#define ICON_TEXTEVENT_SAVE_AS "document-save-as"
#define ICON_TEXTEVENT_OPEN "document-open"
#define ICON_TEXTEVENT_OK "dialog-ok"
#endif
#if !HAVE_GTK3
#define ICON_TEXTEVENT_SAVE_AS GTK_STOCK_SAVE_AS
#define ICON_TEXTEVENT_OPEN GTK_STOCK_OPEN
#define ICON_TEXTEVENT_OK GTK_STOCK_OK
#endif
extern struct text_event te[]; extern struct text_event te[];
extern char *pntevts_text[]; extern char *pntevts_text[];
extern char *pntevts[]; extern char *pntevts[];
@@ -451,7 +462,11 @@ pevent_dialog_show ()
TRUE, FALSE, pevent_dialog_close, NULL, TRUE, FALSE, pevent_dialog_close, NULL,
600, 455, &vbox, 0); 600, 455, &vbox, 0);
#if HAVE_GTK3
pane = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
#elif !HAVE_GTK3
pane = gtk_vpaned_new (); pane = gtk_vpaned_new ();
#endif
gtk_box_pack_start (GTK_BOX (vbox), pane, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), pane, TRUE, TRUE, 0);
pevent_dialog_list = pevent_treeview_new (pane); pevent_dialog_list = pevent_treeview_new (pane);
@@ -470,16 +485,21 @@ pevent_dialog_show ()
gtk_container_add (GTK_CONTAINER (wid), pevent_dialog_twid); gtk_container_add (GTK_CONTAINER (wid), pevent_dialog_twid);
gtk_xtext_set_font (GTK_XTEXT (pevent_dialog_twid), prefs.hex_text_font); gtk_xtext_set_font (GTK_XTEXT (pevent_dialog_twid), prefs.hex_text_font);
#if HAVE_GTK3
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
hbox = gtk_hbutton_box_new (); hbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 4);
gtkutil_button (hbox, GTK_STOCK_SAVE_AS, NULL, pevent_save_cb, gtkutil_button (hbox, ICON_TEXTEVENT_SAVE_AS, NULL, pevent_save_cb,
(void *) 1, _("Save As...")); (void *) 1, _("Save As..."));
gtkutil_button (hbox, GTK_STOCK_OPEN, NULL, pevent_load_cb, gtkutil_button (hbox, ICON_TEXTEVENT_OPEN, NULL, pevent_load_cb,
NULL, _("Load From...")); NULL, _("Load From..."));
gtkutil_button (hbox, NULL, NULL, pevent_test_cb, gtkutil_button (hbox, NULL, NULL, pevent_test_cb,
pevent_dialog_twid, _("Test All")); pevent_dialog_twid, _("Test All"));
gtkutil_button (hbox, GTK_STOCK_OK, NULL, pevent_ok_cb, gtkutil_button (hbox, ICON_TEXTEVENT_OK, NULL, pevent_ok_cb,
NULL, _("OK")); NULL, _("OK"));
gtk_widget_show_all (pevent_dialog); gtk_widget_show_all (pevent_dialog);

View File

@@ -33,6 +33,17 @@
#include "maingui.h" #include "maingui.h"
#include "urlgrab.h" #include "urlgrab.h"
#if HAVE_GTK3
#define ICON_URLGRAB_CLEAR "edit-clear"
#define ICON_URLGRAB_COPY "edit-copy"
#define ICON_URLGRAB_SAVE_AS "document-save-as"
#endif
#if !HAVE_GTK3
#define ICON_URLGRAB_CLEAR GTK_STOCK_CLEAR
#define ICON_URLGRAB_COPY GTK_STOCK_COPY
#define ICON_URLGRAB_SAVE_AS GTK_STOCK_SAVE_AS
#endif
/* model for the URL treeview */ /* model for the URL treeview */
enum enum
{ {
@@ -87,13 +98,16 @@ static GtkWidget *
url_treeview_new (GtkWidget *box) url_treeview_new (GtkWidget *box)
{ {
GtkListStore *store; GtkListStore *store;
GtkWidget *view; GtkWidget *scroll, *view;
store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING); store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
g_return_val_if_fail (store != NULL, NULL); g_return_val_if_fail (store != NULL, NULL);
view = gtkutil_treeview_new (box, GTK_TREE_MODEL (store), NULL, view = gtkutil_treeview_new (box, GTK_TREE_MODEL (store), NULL,
URL_COLUMN, _("URL"), -1); URL_COLUMN, _("URL"), -1);
scroll = gtk_widget_get_parent (view);
gtk_widget_set_hexpand (scroll, TRUE);
gtk_widget_set_vexpand (scroll, TRUE);
g_signal_connect (G_OBJECT (view), "button_press_event", g_signal_connect (G_OBJECT (view), "button_press_event",
G_CALLBACK (url_treeview_url_clicked_cb), NULL); G_CALLBACK (url_treeview_url_clicked_cb), NULL);
/* don't want column headers */ /* don't want column headers */
@@ -204,17 +218,22 @@ url_opengui ()
g_object_set_data (G_OBJECT (urlgrabberwindow), "model", g_object_set_data (G_OBJECT (urlgrabberwindow), "model",
gtk_tree_view_get_model (GTK_TREE_VIEW (view))); gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
#if HAVE_GTK3
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#elif !HAVE_GTK3
hbox = gtk_hbutton_box_new (); hbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
gtk_box_pack_end (GTK_BOX (vbox), hbox, 0, 0, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, 0, 0, 0);
gtk_widget_show (hbox); gtk_widget_show (hbox);
gtkutil_button (hbox, GTK_STOCK_CLEAR, gtkutil_button (hbox, ICON_URLGRAB_CLEAR,
_("Clear list"), url_button_clear, 0, _("Clear")); _("Clear list"), url_button_clear, 0, _("Clear"));
gtkutil_button (hbox, GTK_STOCK_COPY, gtkutil_button (hbox, ICON_URLGRAB_COPY,
_("Copy selected URL"), url_button_copy, view, _("Copy")); _("Copy selected URL"), url_button_copy, view, _("Copy"));
gtkutil_button (hbox, GTK_STOCK_SAVE_AS, gtkutil_button (hbox, ICON_URLGRAB_SAVE_AS,
_("Save list to a file"), url_button_save, 0, _("Save As...")); _("Save list to a file"), url_button_save, 0, _("Save As..."));
gtk_widget_show (urlgrabberwindow); gtk_widget_show (urlgrabberwindow);

View File

@@ -46,9 +46,10 @@ enum
COL_NICK=1, /* char * */ COL_NICK=1, /* char * */
COL_HOST=2, /* char * */ COL_HOST=2, /* char * */
COL_USER=3, /* struct User * */ COL_USER=3, /* struct User * */
COL_GDKCOLOR=4 /* GdkColor * */ COL_GDKCOLOR=4 /* PaletteColor */
}; };
static void userlist_store_color (GtkListStore *store, GtkTreeIter *iter, int color_index);
GdkPixbuf * GdkPixbuf *
get_user_icon (server *serv, struct User *user) get_user_icon (server *serv, struct User *user)
@@ -327,8 +328,8 @@ fe_userlist_rehash (session *sess, struct User *user)
gtk_list_store_set (GTK_LIST_STORE (sess->res->user_model), iter, gtk_list_store_set (GTK_LIST_STORE (sess->res->user_model), iter,
COL_HOST, user->hostname, COL_HOST, user->hostname,
COL_GDKCOLOR, nick_color ? &colors[nick_color] : NULL,
-1); -1);
userlist_store_color (GTK_LIST_STORE (sess->res->user_model), iter, nick_color);
} }
void void
@@ -362,8 +363,8 @@ fe_userlist_insert (session *sess, struct User *newuser, gboolean sel)
COL_NICK, nick, COL_NICK, nick,
COL_HOST, newuser->hostname, COL_HOST, newuser->hostname,
COL_USER, newuser, COL_USER, newuser,
COL_GDKCOLOR, nick_color ? &colors[nick_color] : NULL,
-1); -1);
userlist_store_color (GTK_LIST_STORE (model), &iter, nick_color);
if (!prefs.hex_gui_ulist_icons) if (!prefs.hex_gui_ulist_icons)
{ {
@@ -467,6 +468,26 @@ userlist_ops_cmp (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b,
return nick_cmp_az_ops (((session*)userdata)->server, user_a, user_b); return nick_cmp_az_ops (((session*)userdata)->server, user_a, user_b);
} }
static void
userlist_store_color (GtkListStore *store, GtkTreeIter *iter, int color_index)
{
const PaletteColor *color = color_index ? &colors[color_index] : NULL;
#if HAVE_GTK3
if (color)
{
GdkRGBA rgba = *color;
gtk_list_store_set (store, iter, COL_GDKCOLOR, &rgba, -1);
}
else
{
gtk_list_store_set (store, iter, COL_GDKCOLOR, NULL, -1);
}
#else
gtk_list_store_set (store, iter, COL_GDKCOLOR, color, -1);
#endif
}
GtkListStore * GtkListStore *
userlist_create_model (session *sess) userlist_create_model (session *sess)
{ {
@@ -475,7 +496,7 @@ userlist_create_model (session *sess)
GtkSortType sort_type; GtkSortType sort_type;
store = gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, store = gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_POINTER, GDK_TYPE_COLOR); G_TYPE_POINTER, PALETTE_GDK_TYPE);
switch (prefs.hex_gui_ulist_sort) switch (prefs.hex_gui_ulist_sort)
{ {
@@ -528,7 +549,7 @@ userlist_add_columns (GtkTreeView * treeview)
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1); gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-1, NULL, renderer, -1, NULL, renderer,
"text", 1, "foreground-gdk", 4, NULL); "text", 1, PALETTE_FOREGROUND_PROPERTY, 4, NULL);
if (prefs.hex_gui_ulist_show_hosts) if (prefs.hex_gui_ulist_show_hosts)
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -21,9 +21,15 @@
#define ZOITECHAT_XTEXT_H #define ZOITECHAT_XTEXT_H
#include <gtk/gtk.h> #include <gtk/gtk.h>
#if !defined(GTK_MAJOR_VERSION) || GTK_MAJOR_VERSION < 3
#include <gtk/gtkobject.h>
#endif
#include <cairo.h> #include <cairo.h>
#include "xtext-color.h" #include "xtext-color.h"
typedef struct _GtkXText GtkXText;
typedef struct _GtkXTextClass GtkXTextClass;
#define GTK_TYPE_XTEXT (gtk_xtext_get_type ()) #define GTK_TYPE_XTEXT (gtk_xtext_get_type ())
#define GTK_XTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_XTEXT, GtkXText)) #define GTK_XTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_XTEXT, GtkXText))
#define GTK_XTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_XTEXT, GtkXTextClass)) #define GTK_XTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_XTEXT, GtkXTextClass))
@@ -31,6 +37,8 @@
#define GTK_IS_XTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_XTEXT)) #define GTK_IS_XTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_XTEXT))
#define GTK_XTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_XTEXT, GtkXTextClass)) #define GTK_XTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_XTEXT, GtkXTextClass))
GType gtk_xtext_get_type (void);
#define ATTR_BOLD '\002' #define ATTR_BOLD '\002'
#define ATTR_COLOR '\003' #define ATTR_COLOR '\003'
#define ATTR_BLINK '\006' #define ATTR_BLINK '\006'
@@ -52,9 +60,6 @@
#define XTEXT_BG 35 #define XTEXT_BG 35
#define XTEXT_MARKER 36 /* for marker line */ #define XTEXT_MARKER 36 /* for marker line */
#define XTEXT_MAX_COLOR 41 #define XTEXT_MAX_COLOR 41
typedef struct _GtkXText GtkXText;
typedef struct _GtkXTextClass GtkXTextClass;
typedef struct textentry textentry; typedef struct textentry textentry;
/* /*
@@ -125,7 +130,11 @@ typedef struct {
struct _GtkXText struct _GtkXText
{ {
GtkWidget widget; #if HAVE_GTK3
GtkWidget parent_instance;
#else
GtkWidget parent;
#endif
xtext_buffer *buffer; xtext_buffer *buffer;
xtext_buffer *orig_buffer; xtext_buffer *orig_buffer;
@@ -135,6 +144,7 @@ struct _GtkXText
cairo_surface_t *background_surface; /* 0 = use palette[19] */ cairo_surface_t *background_surface; /* 0 = use palette[19] */
GdkWindow *draw_window; /* points to ->window */ GdkWindow *draw_window; /* points to ->window */
cairo_surface_t *draw_surface; /* temporary surface for offscreen draws */ cairo_surface_t *draw_surface; /* temporary surface for offscreen draws */
cairo_t *draw_cr; /* GTK3 draw context */
GdkCursor *hand_cursor; GdkCursor *hand_cursor;
GdkCursor *resize_cursor; GdkCursor *resize_cursor;
@@ -293,6 +303,5 @@ xtext_buffer *gtk_xtext_buffer_new (GtkXText *xtext);
void gtk_xtext_buffer_free (xtext_buffer *buf); void gtk_xtext_buffer_free (xtext_buffer *buf);
void gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render); void gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render);
void gtk_xtext_copy_selection (GtkXText *xtext); void gtk_xtext_copy_selection (GtkXText *xtext);
GType gtk_xtext_get_type (void);
#endif #endif

View File

@@ -1,7 +1,7 @@
#include <winver.h> #include <winver.h>
#include "config.h" #include "config.h"
#define COMMA_VERSION <#= [string]::Join(',', $versionParts) #>,0 #define COMMA_VERSION <#= [string]::Join(',', ($versionParts | %{ ($_ -split '[^0-9]')[0] })) #>,0
XC_ICON ICON "<#= $env:SOLUTIONDIR -replace '\\', '/' #>data/icons/zoitechat.ico" XC_ICON ICON "<#= $env:SOLUTIONDIR -replace '\\', '/' #>data/icons/zoitechat.ico"

View File

@@ -30,7 +30,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@@ -44,7 +44,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_CONSOLE;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_CONSOLE;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ZoiteChatLib);$(DepsRoot)\include;$(OpenSslInclude);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View File

@@ -32,7 +32,7 @@
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\common;$(ZoiteChatLib);$(DepsRoot)\include\enchant;$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\common;$(ZoiteChatLib);$(DepsRoot)\include\enchant;$(DepsRoot)\include;$(OpenSslInclude);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>

View File

@@ -1,102 +1,118 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration"> <PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|x64"> <ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{C9B735E4-75BC-45AC-A5E3-39A6D076F912}</ProjectGuid> <ProjectGuid>{C9B735E4-75BC-45AC-A5E3-39A6D076F912}</ProjectGuid>
<RootNamespace>copy</RootNamespace> <RootNamespace>copy</RootNamespace>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\zoitechat.props" /> <Import Project="..\zoitechat.props" />
<ItemGroup> <ItemGroup>
<None Include="$(DepsRoot)\bin\cert.pem" /> <None Include="$(DepsRoot)\bin\cert.pem" />
<None Include="$(DepsRoot)\bin\atk-1.0-0.dll" /> <None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper.exe" />
<None Include="$(DepsRoot)\bin\cairo.dll" /> <None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper-console.exe" />
<None Include="$(DepsRoot)\bin\freetype.dll" /> <None Include="$(WinSparklePath)\WinSparkle.dll" />
<None Include="$(DepsRoot)\bin\fribidi-0.dll" /> <None Include="changelog.url" />
<None Include="$(DepsRoot)\bin\fontconfig.dll" /> <None Include="readme.url" />
<None Include="$(DepsRoot)\bin\gdk_pixbuf-2.0-0.dll" />
<None Include="$(DepsRoot)\bin\gdk-win32-2.0.dll" /> <None Include="$(DepsRoot)\bin\lua51.dll" />
<None Include="$(DepsRoot)\bin\gio-2.0-0.dll" /> </ItemGroup>
<None Include="$(DepsRoot)\bin\glib-2.0-0.dll" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<None Include="$(DepsRoot)\bin\gmodule-2.0-0.dll" /> <Target Name="Build">
<None Include="$(DepsRoot)\bin\gobject-2.0-0.dll" /> <ItemGroup>
<None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper.exe" /> <None Include="$(DepsRoot)\bin\*atk-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper-console.exe" /> <None Include="$(DepsRoot)\bin\*cairo*.dll" />
<None Include="$(DepsRoot)\bin\gthread-2.0-0.dll" /> <None Include="$(DepsRoot)\bin\*freetype*.dll" />
<None Include="$(DepsRoot)\bin\gtk-win32-2.0.dll" /> <None Include="$(DepsRoot)\bin\*fribidi*.dll" />
<None Include="$(DepsRoot)\bin\iconv.dll" /> <None Include="$(DepsRoot)\bin\*fontconfig*.dll" />
<None Include="$(DepsRoot)\bin\libcrypto*.dll" /> <None Include="$(DepsRoot)\bin\*gdk_pixbuf*.dll" />
<None Include="$(DepsRoot)\bin\libssl*.dll" /> <None Include="$(DepsRoot)\bin\*gdk-3*.dll" />
<None Include="$(DepsRoot)\bin\libenchant.dll" /> <None Include="$(DepsRoot)\bin\*epoxy*.dll" />
<None Include="$(DepsRoot)\bin\ffi-7.dll" /> <None Include="$(DepsRoot)\bin\*gio-2*.dll" />
<None Include="$(DepsRoot)\bin\intl.dll" /> <None Include="$(DepsRoot)\bin\*glib-2*.dll" />
<None Include="$(DepsRoot)\bin\libpng16.dll" /> <None Include="$(DepsRoot)\bin\*gmodule-2*.dll" />
<None Include="$(DepsRoot)\bin\libxml2.dll" /> <None Include="$(DepsRoot)\bin\*gobject-2*.dll" />
<None Include="$(DepsRoot)\bin\pango-1.0-0.dll" /> <None Include="$(DepsRoot)\bin\*gthread-2*.dll" />
<None Include="$(DepsRoot)\bin\pangocairo-1.0-0.dll" /> <None Include="$(DepsRoot)\bin\*gtk-3*.dll" />
<None Include="$(DepsRoot)\bin\pangoft2-1.0-0.dll" /> <None Include="$(DepsRoot)\bin\*iconv*.dll" />
<None Include="$(DepsRoot)\bin\pangowin32-1.0-0.dll" /> <None Include="$(DepsRoot)\bin\*crypto*.dll" />
<None Include="$(DepsRoot)\bin\zlib1.dll" /> <None Include="$(DepsRoot)\bin\*ssl*.dll" />
<None Include="$(WinSparklePath)\WinSparkle.dll" /> <None Include="$(DepsRoot)\bin\*enchant*.dll" />
<None Include="changelog.url" /> <None Include="$(DepsRoot)\bin\*ffi*.dll" />
<None Include="readme.url" /> <None Include="$(DepsRoot)\bin\*intl*.dll" />
<None Include="$(DepsRoot)\bin\*jpeg*.dll" />
<None Include="$(DepsRoot)\bin\lua51.dll" /> <None Include="$(DepsRoot)\bin\*png*.dll" />
<None Include="$(DepsRoot)\bin\girepository-1.0-1.dll" /> <None Include="$(DepsRoot)\bin\*pcre2-8*.dll" />
<LuaLib Include="$(DepsRoot)\lib\lua\**\*.dll" /> <None Include="$(DepsRoot)\bin\*pixman-1*.dll" />
<LuaShare Include="$(DepsRoot)\share\lua\*.lua" /> <None Include="$(DepsRoot)\bin\*tiff*.dll" />
<LuaShare Include="$(DepsRoot)\share\lua\**\*.lua" /> <None Include="$(DepsRoot)\bin\*harfbuzz*.dll" />
<LuaShare Include="$(DepsRoot)\share\lua\**\**\*.lua" /> <None Include="$(DepsRoot)\bin\*expat*.dll" />
<Typelib Include="$(DepsRoot)\lib\girepository-1.0\*.typelib" /> <None Include="$(DepsRoot)\bin\*xml2*.dll" />
<None Include="$(Python3Path)\Lib\site-packages\_cffi_backend.*.pyd" /> <None Include="$(DepsRoot)\bin\*pango-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\*pangocairo-1.0-0.dll" />
<Engines Include="$(DepsRoot)\lib\gtk-2.0\i686-pc-vs14\engines\**\*" /> <None Include="$(DepsRoot)\bin\*pangoft2-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\*pangowin32-1.0-0.dll" />
<FontConfig Include="$(DepsRoot)\etc\fonts\*"/> <None Include="$(DepsRoot)\bin\*zlib*.dll" />
<None Include="$(DepsRoot)\bin\luajit*.dll" />
<Share Include="share\**\*" /> <None Include="$(DepsRoot)\bin\*girepository*.dll" />
<None Include="$(Python3Path)\Lib\site-packages\_cffi_backend.*.pyd" />
<DepsRootDocs Include="$(DepsRoot)\share\doc\**\*" />
<LuaLib Include="$(DepsRoot)\lib\lua\**\*.dll" />
<Locale Include="$(ZoiteChatBin)locale\**\*;$(DepsRoot)\share\locale\**\*" /> <LuaShare Include="$(DepsRoot)\share\lua\*.lua" />
<LuaShare Include="$(DepsRoot)\share\lua\**\*.lua" />
<MSWindowsTheme Include="$(DepsRoot)\share\themes\MS-Windows\**\*" /> <LuaShare Include="$(DepsRoot)\share\lua\**\**\*.lua" />
</ItemGroup> <Typelib Include="$(DepsRoot)\lib\girepository-1.0\*.typelib" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <EnchantProviders Include="$(DepsRoot)\lib\enchant\*.dll" />
<Target Name="Build">
<Copy SourceFiles="@(None)" DestinationFolder="$(ZoiteChatRel)" /> <Gtk3Immodules Include="$(DepsRoot)\lib\gtk-3.0\3.0.0\immodules\**\*" />
<Copy SourceFiles="@(FontConfig)" DestinationFolder="$(ZoiteChatRel)\etc\fonts" /> <Gtk3PrintBackends Include="$(DepsRoot)\lib\gtk-3.0\3.0.0\printbackends\**\*" />
<Copy SourceFiles="@(Engines)" DestinationFiles="@(Engines->'$(ZoiteChatRel)\lib\gtk-2.0\i686-pc-vs14\engines\%(RecursiveDir)%(Filename)%(Extension)')" /> <GSettingsSchemas Include="$(DepsRoot)\share\glib-2.0\schemas\*" />
<Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(ZoiteChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat" /> <FontConfig Include="$(DepsRoot)\etc\fonts\*" />
<Copy SourceFiles="$(WinSparklePath)\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\WinSparkle" /> <Share Include="share\**\*" />
<Copy SourceFiles="$(DepsRoot)\lib\enchant\libenchant_myspell.dll" DestinationFolder="$(ZoiteChatRel)\lib\enchant" /> <DepsRootDocs Include="$(DepsRoot)\share\doc\**\*" />
<Copy SourceFiles="@(Locale)" DestinationFiles="@(Locale->'$(ZoiteChatRel)\share\locale\%(RecursiveDir)%(Filename)%(Extension)')" /> <Locale Include="$(ZoiteChatBin)locale\**\*;$(DepsRoot)\share\locale\**\*" />
<Copy SourceFiles="@(MSWindowsTheme)" DestinationFiles="@(MSWindowsTheme->'$(ZoiteChatRel)\share\themes\MS-Windows\%(RecursiveDir)%(Filename)%(Extension)')" /> <MSWindowsTheme Include="$(DepsRoot)\share\themes\MS-Windows\**\*" />
<Copy SourceFiles="@(LuaShare)" DestinationFiles="@(LuaShare->'$(ZoiteChatRel)\share\lua\%(RecursiveDir)%(Filename)%(Extension)')" /> </ItemGroup>
<Copy SourceFiles="@(LuaLib)" DestinationFiles="@(LuaLib->'$(ZoiteChatRel)\lib\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(Typelib)" DestinationFiles="@(Typelib->'$(ZoiteChatRel)\lib\girepository-1.0\%(Filename)%(Extension)')" /> <Copy SourceFiles="@(None)" DestinationFolder="$(ZoiteChatRel)" />
<Copy SourceFiles="..\..\plugins\python\xchat.py" DestinationFolder="$(ZoiteChatRel)\python" /> <Copy SourceFiles="@(FontConfig)" DestinationFolder="$(ZoiteChatRel)\etc\fonts" />
<Copy SourceFiles="..\..\plugins\python\zoitechat.py" DestinationFolder="$(ZoiteChatRel)\python" /> <Copy SourceFiles="@(Gtk3Immodules)" DestinationFiles="@(Gtk3Immodules->'$(ZoiteChatRel)\lib\gtk-3.0\3.0.0\immodules\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\plugins\python\_zoitechat.py" DestinationFolder="$(ZoiteChatRel)\python" /> <Copy SourceFiles="@(Gtk3PrintBackends)" DestinationFiles="@(Gtk3PrintBackends->'$(ZoiteChatRel)\lib\gtk-3.0\3.0.0\printbackends\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(GSettingsSchemas)" DestinationFiles="@(GSettingsSchemas->'$(ZoiteChatRel)\share\glib-2.0\schemas\%(Filename)%(Extension)')" />
<WriteLinesToFile File="$(ZoiteChatRel)portable-mode" Lines="2" Overwrite="true" /> <Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(ZoiteChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat" />
<Copy SourceFiles="@(DepsRootDocs)" DestinationFiles="@(DepsRootDocs->'$(ZoiteChatRel)\share\doc\%(RecursiveDir)%(Filename)%(Extension)')" /> <Copy SourceFiles="$(WinSparklePath)\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\WinSparkle" />
</Target> <Copy SourceFiles="@(EnchantProviders)" DestinationFolder="$(ZoiteChatRel)\lib\enchant" />
</Project> <Copy SourceFiles="@(Locale)" DestinationFiles="@(Locale->'$(ZoiteChatRel)\share\locale\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(MSWindowsTheme)" DestinationFiles="@(MSWindowsTheme->'$(ZoiteChatRel)\share\themes\MS-Windows\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(LuaShare)" DestinationFiles="@(LuaShare->'$(ZoiteChatRel)\share\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(LuaLib)" DestinationFiles="@(LuaLib->'$(ZoiteChatRel)\lib\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(Typelib)" DestinationFiles="@(Typelib->'$(ZoiteChatRel)\lib\girepository-1.0\%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\plugins\python\xchat.py" DestinationFolder="$(ZoiteChatRel)\python" />
<Copy SourceFiles="..\..\plugins\python\zoitechat.py" DestinationFolder="$(ZoiteChatRel)\python" />
<Copy SourceFiles="..\..\plugins\python\_zoitechat.py" DestinationFolder="$(ZoiteChatRel)\python" />
<WriteLinesToFile File="$(ZoiteChatRel)portable-mode" Lines="2" Overwrite="true" />
<Copy SourceFiles="@(DepsRootDocs)" DestinationFiles="@(DepsRootDocs->'$(ZoiteChatRel)\share\doc\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
</Project>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration"> <PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
@@ -25,6 +25,11 @@
<PropertyGroup> <PropertyGroup>
<OutDir>$(ZoiteChatRel)</OutDir> <OutDir>$(ZoiteChatRel)</OutDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<IsccPath Condition="'$(IsccPath)'=='' and Exists('$(ProgramFiles(x86))\Inno Setup 6\ISCC.exe')">"$(ProgramFiles(x86))\Inno Setup 6\ISCC.exe"</IsccPath>
<IsccPath Condition="'$(IsccPath)'=='' and Exists('$(ProgramFiles)\Inno Setup 6\ISCC.exe')">"$(ProgramFiles)\Inno Setup 6\ISCC.exe"</IsccPath>
<IsccPath Condition="'$(IsccPath)'==''">ISCC.exe</IsccPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile> <ClCompile>
</ClCompile> </ClCompile>
@@ -37,6 +42,7 @@
<Command> <Command>
<![CDATA[ <![CDATA[
SET SOLUTIONDIR=$(SolutionDir)..\ SET SOLUTIONDIR=$(SolutionDir)..\
if not exist "$(ZoiteChatBin)" mkdir "$(ZoiteChatBin)"
powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\installer\zoitechat.iss.tt" "$(ZoiteChatBin)zoitechat.iss" powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\installer\zoitechat.iss.tt" "$(ZoiteChatBin)zoitechat.iss"
$(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(ZoiteChatBin)zoitechat.iss" $(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(ZoiteChatBin)zoitechat.iss"
]]> ]]>
@@ -46,9 +52,14 @@ $(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(ZoiteChatBin
<ItemGroup> <ItemGroup>
<None Include="wizardimage.bmp" /> <None Include="wizardimage.bmp" />
<None Include="wizardsmallimage.bmp" /> <None Include="wizardsmallimage.bmp" />
<None Include="zoitechat.iss" /> <None Include="zoitechat.iss.tt" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project> </Project>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<Filter Include="Resource Files"> <Filter Include="Resource Files">
@@ -7,10 +7,7 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="zoitechat-x64.skel.iss"> <None Include="zoitechat.iss.tt">
<Filter>Resource Files</Filter>
</None>
<None Include="zoitechat-x86.skel.iss">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
<None Include="wizardimage.bmp"> <None Include="wizardimage.bmp">
@@ -20,4 +17,4 @@
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -5,7 +5,10 @@
;#define PROJECTDIR "C:\...\zoitechat\win32\installer\" ;#define PROJECTDIR "C:\...\zoitechat\win32\installer\"
;http://mitrich.net23.net/?/inno-download-plugin.html ;http://mitrich.net23.net/?/inno-download-plugin.html
#ifexist "idp.iss"
#define USE_INNO_DOWNLOAD_PLUGIN
#include <idp.iss> #include <idp.iss>
#endif
[Setup] [Setup]
AppName=ZoiteChat AppName=ZoiteChat
@@ -110,62 +113,59 @@ Source: "readme.url"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "cert.pem"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "cert.pem"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "share\xml\*"; DestDir: "{app}\share\xml"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs Source: "share\xml\*"; DestDir: "{app}\share\xml"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "share\doc\*"; DestDir: "{app}\share\doc"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs Source: "share\doc\*"; DestDir: "{app}\share\doc"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "share\themes\MS-Windows\*"; DestDir: "{app}\share\themes\MS-Windows"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs Source: "share\themes\MS-Windows\*"; DestDir: "{app}\share\themes\MS-Windows"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
Source: "share\glib-2.0\schemas\*"; DestDir: "{app}\share\glib-2.0\schemas"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
Source: "share\locale\*"; DestDir: "{app}\share\locale"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: translations Source: "share\locale\*"; DestDir: "{app}\share\locale"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: translations
Source: "etc\fonts\*"; DestDir: "{app}\etc\fonts"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs Source: "etc\fonts\*"; DestDir: "{app}\etc\fonts"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
Source: "atk-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "atk-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "cairo.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "cairo-2.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "freetype.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "freetype-6.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "fribidi-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "fribidi-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "fontconfig.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "fontconfig-1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gdk_pixbuf-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gdk_pixbuf-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gdk-win32-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gdk-3-vs17.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "epoxy-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gio-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gio-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "glib-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "glib-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gmodule-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gmodule-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gobject-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gobject-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
#if APPARCH == "x64"
Source: "gspawn-win64-helper.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gspawn-win64-helper.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gspawn-win64-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gspawn-win64-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
#else
Source: "gspawn-win32-helper.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gspawn-win32-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
#endif
Source: "gthread-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gthread-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gtk-win32-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "iconv.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "iconv.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
#if APPARCH == "x64" Source: "libcrypto-3-x64.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "libcrypto-1_1-x64.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "libssl-3-x64.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "libssl-1_1-x64.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
#else
Source: "libcrypto-1_1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "libssl-1_1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
#endif
Source: "libenchant.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "libenchant.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "ffi-7.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "ffi-8.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "intl.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "intl.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "libpng16.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "libpng16.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "libxml2.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "xml2-16.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "pango-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "pango-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "pangocairo-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "pangocairo-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "cairo-gobject-2.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "pangoft2-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "pangoft2-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "pangowin32-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "pangowin32-1.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "jpeg62.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "harfbuzz.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "gtk-3-vs17.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "libexpat.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "pcre2-8-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "pixman-1-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "tiff.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "plugins\hcnotifications-winrt.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: libs Source: "plugins\hcnotifications-winrt.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: libs
Source: "lib\enchant\*"; DestDir: "{app}\lib\enchant"; Flags: ignoreversion; Components: libs Source: "lib\enchant\*"; DestDir: "{app}\lib\enchant"; Flags: ignoreversion; Components: libs
Source: "lib\gtk-2.0\i686-pc-vs14\engines\*"; DestDir: "{app}\lib\gtk-2.0\i686-pc-vs14\engines"; Flags: ignoreversion; Components: libs Source: "girepository-2.0-0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\lua
Source: "girepository-1.0-1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\lua
Source: "lua51.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\lua Source: "lua51.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\lua
Source: "lib\lua\lgi\*.dll"; DestDir: "{app}\lib\lua\lgi"; Flags: ignoreversion; Components: langs\lua Source: "lib\lua\2.1\lgi\*.dll"; DestDir: "{app}\lib\lua\lgi"; Flags: ignoreversion; Components: langs\lua
Source: "lib\girepository-1.0\*.typelib"; DestDir: "{app}\lib\girepository-1.0"; Flags: ignoreversion; Components: langs\lua Source: "lib\girepository-1.0\*.typelib"; DestDir: "{app}\lib\girepository-1.0"; Flags: ignoreversion; Components: langs\lua
Source: "share\lua\*.lua"; DestDir: "{app}\share\lua"; Flags: ignoreversion; Components: langs\lua Source: "share\lua\2.1\*.lua"; DestDir: "{app}\share\lua"; Flags: ignoreversion; Components: langs\lua
Source: "share\lua\lgi\*.lua"; DestDir: "{app}\share\lua\lgi"; Flags: ignoreversion; Components: langs\lua Source: "share\lua\2.1\lgi\*.lua"; DestDir: "{app}\share\lua\lgi"; Flags: ignoreversion; Components: langs\lua
Source: "share\lua\lgi\override\*.lua"; DestDir: "{app}\share\lua\lgi\override"; Flags: ignoreversion; Components: langs\lua Source: "share\lua\2.1\lgi\override\*.lua"; DestDir: "{app}\share\lua\lgi\override"; Flags: ignoreversion; Components: langs\lua
Source: "plugins\hclua.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\lua Source: "plugins\hclua.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\lua
Source: "plugins\hcchecksum.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\checksum Source: "plugins\hcchecksum.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\checksum
@@ -203,6 +203,22 @@ Name: "{commonappdata}\Microsoft\Internet Explorer\Quick Launch\ZoiteChat"; File
BeveledLabel= {#APPNAM} BeveledLabel= {#APPNAM}
[Code] [Code]
#ifndef USE_INNO_DOWNLOAD_PLUGIN
// The Inno Download Plugin isn't always installed in CI environments.
// Provide no-op fallback procedures so installer compilation still succeeds.
procedure idpDownloadAfter(PageID: Integer);
begin
end;
procedure idpClearFiles;
begin
end;
procedure idpAddFile(URL: String; Filename: String);
begin
end;
#endif
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
procedure InitializeWizard; procedure InitializeWizard;
begin begin
@@ -310,8 +326,8 @@ begin
idpAddFile(PERL, ExpandConstant('{tmp}\perl.msi')) idpAddFile(PERL, ExpandConstant('{tmp}\perl.msi'))
end; end;
if IsComponentSelected('langs\python\python3') and not CheckDLL('python314.dll') then if IsComponentSelected('langs\python') and not CheckDLL('python314.dll') then
idpAddFile(PY3, ExpandConstant('{tmp}\python.exe')); idpAddFile(PY3, ExpandConstant('{tmp}\python.exe'));
end; end;
end; end;
end; end;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration"> <PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
@@ -28,7 +28,7 @@
<ItemDefinitionGroup> <ItemDefinitionGroup>
<PreBuildEvent> <PreBuildEvent>
<Command>cd ..\..\po <Command>cd ..\..\po
rmdir /q /s "$(OutDir)\locale" if exist "$(OutDir)\locale" rmdir /q /s "$(OutDir)\locale"
mkdir "$(OutDir)\locale" mkdir "$(OutDir)\locale"
for %%A in (*.po) do ( for %%A in (*.po) do (
mkdir "$(OutDir)\locale\%%~nA\LC_MESSAGES" mkdir "$(OutDir)\locale\%%~nA\LC_MESSAGES"
@@ -40,3 +40,4 @@ mkdir "$(OutDir)\locale\%%~nA\LC_MESSAGES"
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project> </Project>

View File

@@ -1 +1 @@
2.17.4 2.18.0-pre1

View File

@@ -1,83 +1,181 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros"> <PropertyGroup Label="UserMacros">
<!-- SPECIFY YOUR DEPENDENCY DIRECTORIES HERE --> <!-- SPECIFY YOUR DEPENDENCY DIRECTORIES HERE -->
<YourDepsPath>c:\gtk-build\gtk</YourDepsPath> <YourDepsPath>c:\gtk-build\gtk</YourDepsPath>
<YourGendefPath>c:\gtk-build\gendef</YourGendefPath> <YourGendefPath>c:\gtk-build\gendef</YourGendefPath>
<YourPerlPath>c:\gtk-build\perl-5.20</YourPerlPath> <YourPerlPath>c:\gtk-build\perl-5.20</YourPerlPath>
<YourPython3Path>c:\gtk-build\python-3.14</YourPython3Path> <YourPython3Path>c:\gtk-build\python-3.14</YourPython3Path>
<YourWinSparklePath>c:\gtk-build\WinSparkle</YourWinSparklePath> <YourWinSparklePath>c:\gtk-build\WinSparkle</YourWinSparklePath>
<!-- YOU SHOULDN'T TOUCH ANYTHING BELOW --> <!-- YOU SHOULDN'T TOUCH ANYTHING BELOW -->
<!-- G_DISABLE_DEPRECATED is unfeasible due to g_completion_* --> <!-- Force x64 only -->
<!-- must be buildable with GSEAL_ENABLE in the future, xtext, setup, and chanview-tabs stand in the way --> <ZoiteChatPlatform>x64</ZoiteChatPlatform>
<OwnFlags>GTK_DISABLE_DEPRECATED;GDK_PIXBUF_DISABLE_DEPRECATED;G_DISABLE_SINGLE_INCLUDES;GDK_PIXBUF_DISABLE_SINGLE_INCLUDES;GTK_DISABLE_SINGLE_INCLUDES;HAVE_X509_GET_SIGNATURE_NID;HAVE_SSL_CTX_GET_SSL_METHOD;DEFAULT_CERT_FILE="cert.pem";HAVE_STRTOULL;strtoull=_strtoui64;strcasecmp=stricmp;strncasecmp=strnicmp;__inline__=__inline</OwnFlags>
<!-- FIXME: Add ability to use debug builds --> <!-- G_DISABLE_DEPRECATED is unfeasible due to g_completion_* -->
<DepsRoot>$(YourDepsPath)\$(PlatformName)\release</DepsRoot> <!-- must be buildable with GSEAL_ENABLE in the future, xtext, setup, and chanview-tabs stand in the way -->
<GendefPath>$(YourGendefPath)</GendefPath> <OwnFlags>GTK_DISABLE_DEPRECATED;GDK_PIXBUF_DISABLE_DEPRECATED;G_DISABLE_SINGLE_INCLUDES;GDK_PIXBUF_DISABLE_SINGLE_INCLUDES;GTK_DISABLE_SINGLE_INCLUDES;HAVE_X509_GET_SIGNATURE_NID;HAVE_SSL_CTX_GET_SSL_METHOD;DEFAULT_CERT_FILE="cert.pem";HAVE_STRTOULL;strtoull=_strtoui64;strcasecmp=stricmp;strncasecmp=strnicmp;__inline__=__inline;$(GtkDefines)</OwnFlags>
<WinSparklePath>$(YourWinSparklePath)\$(PlatformName)</WinSparklePath>
<PerlPath>$(YourPerlPath)\$(PlatformName)</PerlPath> <!-- FIXME: Add ability to use debug builds -->
<PerlLib>perl520</PerlLib> <DepsRoot>$(YourDepsPath)\$(ZoiteChatPlatform)\release</DepsRoot>
<Python3Path>$(YourPython3Path)\$(PlatformName)</Python3Path> <GendefPath>$(YourGendefPath)</GendefPath>
<Python3Lib>python314</Python3Lib> <WinSparklePath>$(YourWinSparklePath)\$(ZoiteChatPlatform)</WinSparklePath>
<Python3Output>hcpython3</Python3Output> <PerlPath>$(YourPerlPath)\$(ZoiteChatPlatform)</PerlPath>
<LuaInclude>$(DepsRoot)\include\luajit-2.1</LuaInclude> <PerlLib>perl520</PerlLib>
<LuaOutput>hclua</LuaOutput>
<LuaLib>lua51</LuaLib> <Python3Path>$(YourPython3Path)\$(ZoiteChatPlatform)</Python3Path>
<Glib>$(DepsRoot)\include\glib-2.0;$(DepsRoot)\lib\glib-2.0\include;$(DepsRoot)\include\libxml2</Glib> <Python3Lib>python314</Python3Lib>
<Gtk>$(DepsRoot)\include\gtk-2.0;$(DepsRoot)\lib\gtk-2.0\include;$(DepsRoot)\include\atk-1.0;$(DepsRoot)\include\cairo;$(DepsRoot)\include\pango-1.0;$(DepsRoot)\include\gdk-pixbuf-2.0</Gtk> <Python3Output>hcpython3</Python3Output>
<DepLibs>gtk-win32-2.0.lib;gdk-win32-2.0.lib;atk-1.0.lib;gio-2.0.lib;gdk_pixbuf-2.0.lib;pangowin32-1.0.lib;pangocairo-1.0.lib;pango-1.0.lib;cairo.lib;gobject-2.0.lib;gmodule-2.0.lib;glib-2.0.lib;intl.lib;libxml2.lib;libcrypto.lib;libssl.lib;ssleay32.lib;wininet.lib;winmm.lib;ws2_32.lib</DepLibs> <Python3Enabled Condition="Exists('$(Python3Path)\\python.exe') and Exists('$(Python3Path)\\libs\\$(Python3Lib).lib') and Exists('$(Python3Path)\\Lib\\site-packages\\cffi')">true</Python3Enabled>
<DataDir>$(SolutionDir)..\data\\</DataDir> <Python3Enabled Condition="'$(Python3Enabled)'==''">false</Python3Enabled>
<ZoiteChatBuild>$(SolutionDir)..\..\zoitechat-build</ZoiteChatBuild>
<ZoiteChatBin>$(ZoiteChatBuild)\$(PlatformName)\bin\</ZoiteChatBin> <PerlEnabled Condition="Exists('$(PerlPath)\\bin\\perl.exe') and Exists('$(PerlPath)\\bin\\$(PerlLib).dll') and Exists('$(GendefPath)\\gendef.exe')">true</PerlEnabled>
<ZoiteChatObj>$(ZoiteChatBuild)\$(PlatformName)\obj\</ZoiteChatObj> <PerlEnabled Condition="'$(PerlEnabled)'==''">false</PerlEnabled>
<ZoiteChatLib>$(ZoiteChatBuild)\$(PlatformName)\lib\</ZoiteChatLib>
<ZoiteChatPdb>$(ZoiteChatBuild)\$(PlatformName)\pdb\</ZoiteChatPdb> <InstallerEnabled Condition="Exists('$(IsccPath)')">true</InstallerEnabled>
<ZoiteChatRel>$(ZoiteChatBuild)\$(PlatformName)\rel\</ZoiteChatRel> <InstallerEnabled Condition="'$(InstallerEnabled)'==''">false</InstallerEnabled>
<IsccPath>"$(ProgramFiles)\Inno Setup 5\iscc.exe"</IsccPath>
</PropertyGroup> <LuaInclude Condition="Exists('$(DepsRoot)\include\luajit-2.1\lua.h')">$(DepsRoot)\include\luajit-2.1</LuaInclude>
<LuaInclude Condition="'$(LuaInclude)'=='' and Exists('$(DepsRoot)\include\luajit\lua.h')">$(DepsRoot)\include\luajit</LuaInclude>
<PropertyGroup> <LuaInclude Condition="'$(LuaInclude)'=='' and Exists('$(DepsRoot)\include\lua5.1\lua.h')">$(DepsRoot)\include\lua5.1</LuaInclude>
<LinkIncremental>false</LinkIncremental> <LuaInclude Condition="'$(LuaInclude)'=='' and Exists('$(DepsRoot)\include\lua51\lua.h')">$(DepsRoot)\include\lua51</LuaInclude>
<IntDir>$(ZoiteChatObj)$(ProjectName)\</IntDir> <LuaOutput>hclua</LuaOutput>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <LuaLib Condition="Exists('$(DepsRoot)\lib\lua51.lib')">lua51</LuaLib>
<CharacterSet>MultiByte</CharacterSet> <LuaLib Condition="'$(LuaLib)'=='' and Exists('$(DepsRoot)\lib\luajit-5.1.lib')">luajit-5.1</LuaLib>
</PropertyGroup> <LuaLib Condition="'$(LuaLib)'=='' and Exists('$(DepsRoot)\lib\luajit.lib')">luajit</LuaLib>
<LuaEnabled Condition="'$(LuaInclude)'!='' and '$(LuaLib)'!=''">true</LuaEnabled>
<ItemDefinitionGroup>
<ClCompile> <LuaRuntimeDll Condition="Exists('$(DepsRoot)\bin\lua51.dll')">lua51.dll</LuaRuntimeDll>
<WarningLevel>Level3</WarningLevel> <LuaRuntimeDll Condition="'$(LuaRuntimeDll)'=='' and Exists('$(DepsRoot)\bin\luajit-5.1.dll')">luajit-5.1.dll</LuaRuntimeDll>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <LuaRuntimeDll Condition="'$(LuaRuntimeDll)'=='' and Exists('$(DepsRoot)\bin\luajit.dll')">luajit.dll</LuaRuntimeDll>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> <LuaShareDir Condition="Exists('$(DepsRoot)\share\lua\2.1\lgi\init.lua')">$(DepsRoot)\share\lua\2.1</LuaShareDir>
<WholeProgramOptimization>true</WholeProgramOptimization> <LuaShareDir Condition="'$(LuaShareDir)'=='' and Exists('$(DepsRoot)\share\lua\5.1\lgi\init.lua')">$(DepsRoot)\share\lua\5.1</LuaShareDir>
<!-- UNCOMMENT ONLY ONE -->
<!--Optimization>Disabled</Optimization--> <LuaLibDir Condition="Exists('$(DepsRoot)\lib\lua\2.1\lgi')">$(DepsRoot)\lib\lua\2.1</LuaLibDir>
<Optimization>MaxSpeed</Optimization> <LuaLibDir Condition="'$(LuaLibDir)'=='' and Exists('$(DepsRoot)\lib\lua\5.1\lgi')">$(DepsRoot)\lib\lua\5.1</LuaLibDir>
<!--Optimization>MinSpace</Optimization-->
<!--Optimization>Full</Optimization--> <LuaEnabled Condition="'$(LuaEnabled)'==''">false</LuaEnabled>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <GlibGenMarshal Condition="Exists('$(DepsRoot)\bin\glib-genmarshal.exe')">"$(DepsRoot)\bin\glib-genmarshal.exe"</GlibGenMarshal>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <GlibGenMarshal Condition="'$(GlibGenMarshal)'=='' and Exists('$(DepsRoot)\bin\glib-genmarshal') and Exists('$(Python3Path)\python.exe')">"$(Python3Path)\python.exe" "$(DepsRoot)\bin\glib-genmarshal"</GlibGenMarshal>
<PreProcessorDefinitions>NTDDI_VERSION=NTDDI_WIN8;_WIN32_WINNT=_WIN32_WINNT_WIN8;%(PreProcessorDefinitions)</PreProcessorDefinitions>
</ClCompile> <Glib>$(DepsRoot)\include\glib-2.0;$(DepsRoot)\lib\glib-2.0\include;$(DepsRoot)\include\libxml2</Glib>
<Lib>
<LinkTimeCodeGeneration>true</LinkTimeCodeGeneration> <UsingGtk3 Condition="Exists('$(DepsRoot)\\include\\gtk-3.0\\gtk\\gtk.h')">true</UsingGtk3>
</Lib> <GtkDefines>HAVE_GTK3</GtkDefines>
<Link> <Gtk3>$(DepsRoot)\include\gtk-3.0;$(DepsRoot)\lib\gtk-3.0\include</Gtk3>
<ImportLibrary>$(ZoiteChatLib)$(TargetName).lib</ImportLibrary> <GtkCommon>$(DepsRoot)\include\atk-1.0;$(DepsRoot)\include\cairo;$(DepsRoot)\include\pango-1.0;$(DepsRoot)\include\gdk-pixbuf-2.0;$(DepsRoot)\include\harfbuzz</GtkCommon>
<ProgramDatabaseFile>$(ZoiteChatPdb)$(TargetName).pdb</ProgramDatabaseFile> <Gtk>$(Gtk3);$(GtkCommon)</Gtk>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>Debug</GenerateDebugInformation> <SslLegacyLib Condition="Exists('$(DepsRoot)\\lib\\ssleay32.lib')">ssleay32.lib</SslLegacyLib>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <CryptoLegacyLib Condition="Exists('$(DepsRoot)\\lib\\libeay32.lib')">libeay32.lib</CryptoLegacyLib>
<OptimizeReferences>true</OptimizeReferences> <SslModernLib Condition="Exists('$(DepsRoot)\\lib\\libssl.lib')">libssl.lib</SslModernLib>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> <CryptoModernLib Condition="Exists('$(DepsRoot)\\lib\\libcrypto.lib')">libcrypto.lib</CryptoModernLib>
</Link>
</ItemDefinitionGroup> <OpenSslLibs Condition="'$(SslModernLib)' != '' and '$(CryptoModernLib)' != ''">$(SslModernLib);$(CryptoModernLib)</OpenSslLibs>
<OpenSslLibs Condition="'$(OpenSslLibs)' == '' and '$(SslLegacyLib)' != '' and '$(CryptoLegacyLib)' != ''">$(SslLegacyLib);$(CryptoLegacyLib)</OpenSslLibs>
<ItemGroup /> <OpenSslInclude Condition="Exists('$(DepsRoot)\\include\\openssl\\ssl.h')">$(DepsRoot)\include</OpenSslInclude>
</Project>
<!-- Resolve library names across dependency bundles -->
<Gtk3Lib Condition="Exists('$(DepsRoot)\lib\gtk-3.lib')">gtk-3.lib</Gtk3Lib>
<Gtk3Lib Condition="'$(Gtk3Lib)'=='' and Exists('$(DepsRoot)\lib\gtk-3.0.lib')">gtk-3.0.lib</Gtk3Lib>
<Gtk3Lib Condition="'$(Gtk3Lib)'=='' and Exists('$(DepsRoot)\lib\libgtk-3.lib')">libgtk-3.lib</Gtk3Lib>
<Gtk3Lib Condition="'$(Gtk3Lib)'=='' and Exists('$(DepsRoot)\lib\libgtk-3.0.lib')">libgtk-3.0.lib</Gtk3Lib>
<Gdk3Lib Condition="Exists('$(DepsRoot)\lib\gdk-3.lib')">gdk-3.lib</Gdk3Lib>
<Gdk3Lib Condition="'$(Gdk3Lib)'=='' and Exists('$(DepsRoot)\lib\gdk-3.0.lib')">gdk-3.0.lib</Gdk3Lib>
<Gdk3Lib Condition="'$(Gdk3Lib)'=='' and Exists('$(DepsRoot)\lib\libgdk-3.lib')">libgdk-3.lib</Gdk3Lib>
<Gdk3Lib Condition="'$(Gdk3Lib)'=='' and Exists('$(DepsRoot)\lib\libgdk-3.0.lib')">libgdk-3.0.lib</Gdk3Lib>
<IntlLib Condition="Exists('$(DepsRoot)\lib\intl.lib')">intl.lib</IntlLib>
<IntlLib Condition="'$(IntlLib)'=='' and Exists('$(DepsRoot)\lib\libintl.lib')">libintl.lib</IntlLib>
<IconvLib Condition="Exists('$(DepsRoot)\lib\iconv.lib')">iconv.lib</IconvLib>
<IconvLib Condition="'$(IconvLib)'=='' and Exists('$(DepsRoot)\lib\libiconv.lib')">libiconv.lib</IconvLib>
<ZlibLib Condition="Exists('$(DepsRoot)\lib\zlib1.lib')">zlib1.lib</ZlibLib>
<ZlibLib Condition="'$(ZlibLib)'=='' and Exists('$(DepsRoot)\lib\zlib.lib')">zlib.lib</ZlibLib>
<Xml2Lib Condition="Exists('$(DepsRoot)\lib\libxml2.lib')">libxml2.lib</Xml2Lib>
<Xml2Lib Condition="'$(Xml2Lib)'=='' and Exists('$(DepsRoot)\lib\xml2.lib')">xml2.lib</Xml2Lib>
<Xml2Lib Condition="'$(Xml2Lib)'=='' and Exists('$(DepsRoot)\lib\libxml2-2.lib')">libxml2-2.lib</Xml2Lib>
<JpegLib Condition="Exists('$(DepsRoot)\lib\jpeg.lib')">jpeg.lib</JpegLib>
<JpegLib Condition="'$(JpegLib)'=='' and Exists('$(DepsRoot)\lib\libjpeg.lib')">libjpeg.lib</JpegLib>
<JpegLib Condition="'$(JpegLib)'=='' and Exists('$(DepsRoot)\lib\libjpeg-8.lib')">libjpeg-8.lib</JpegLib>
<JpegLib Condition="'$(JpegLib)'=='' and Exists('$(DepsRoot)\lib\libjpeg-9.lib')">libjpeg-9.lib</JpegLib>
<PngLib Condition="Exists('$(DepsRoot)\lib\libpng16.lib')">libpng16.lib</PngLib>
<PngLib Condition="'$(PngLib)'=='' and Exists('$(DepsRoot)\lib\libpng16_static.lib')">libpng16_static.lib</PngLib>
<PngLib Condition="'$(PngLib)'=='' and Exists('$(DepsRoot)\lib\libpng.lib')">libpng.lib</PngLib>
<DepLibs>$(Gtk3Lib);$(Gdk3Lib);wininet.lib;winmm.lib;ws2_32.lib;atk-1.0.lib;gio-2.0.lib;gdk_pixbuf-2.0.lib;pangowin32-1.0.lib;pangocairo-1.0.lib;pango-1.0.lib;cairo.lib;gobject-2.0.lib;gmodule-2.0.lib;glib-2.0.lib;$(IntlLib);$(IconvLib);$(ZlibLib);$(Xml2Lib);$(JpegLib);$(PngLib);$(OpenSslLibs)</DepLibs>
<DataDir>$(SolutionDir)..\data\\</DataDir>
<ZoiteChatBuild>$(SolutionDir)..\..\zoitechat-build</ZoiteChatBuild>
<ZoiteChatBin>$(ZoiteChatBuild)\$(ZoiteChatPlatform)\bin\</ZoiteChatBin>
<ZoiteChatObj>$(ZoiteChatBuild)\$(ZoiteChatPlatform)\obj\</ZoiteChatObj>
<ZoiteChatLib>$(ZoiteChatBuild)\$(ZoiteChatPlatform)\lib\</ZoiteChatLib>
<ZoiteChatPdb>$(ZoiteChatBuild)\$(ZoiteChatPlatform)\pdb\</ZoiteChatPdb>
<ZoiteChatRel>$(ZoiteChatBuild)\$(ZoiteChatPlatform)\rel\</ZoiteChatRel>
<IsccPath Condition="'$(IsccPath)'=='' and Exists('$(ProgramFiles(x86))\Inno Setup 6\ISCC.exe')">"$(ProgramFiles(x86))\Inno Setup 6\ISCC.exe"</IsccPath>
<IsccPath Condition="'$(IsccPath)'=='' and Exists('$(ProgramFiles)\Inno Setup 6\ISCC.exe')">"$(ProgramFiles)\Inno Setup 6\ISCC.exe"</IsccPath>
</PropertyGroup>
<!-- If someone tries Win32, stop immediately. -->
<PropertyGroup>
<_ZoiteChatPlatformMismatch Condition="'$(Platform)'!='x64' and '$(PlatformName)'!='x64'">true</_ZoiteChatPlatformMismatch>
</PropertyGroup>
<Target Name="ZoiteChatPropsEnforceX64" BeforeTargets="PrepareForBuild" Condition="'$(_ZoiteChatPlatformMismatch)'=='true'">
<Error Text="zoitechat.props is configured for x64 only. Set the Solution/Project Platform to x64." />
</Target>
<PropertyGroup>
<LinkIncremental>false</LinkIncremental>
<IntDir>$(ZoiteChatObj)$(ProjectName)\</IntDir>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
<AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
<WholeProgramOptimization>false</WholeProgramOptimization>
<!-- UNCOMMENT ONLY ONE -->
<!--<Optimization>Disabled</Optimization>-->
<!--Optimization>MaxSpeed</Optimization-->
<!--Optimization>MinSpace</Optimization-->
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreProcessorDefinitions>NTDDI_VERSION=NTDDI_WIN8;_WIN32_WINNT=_WIN32_WINNT_WIN8;%(PreProcessorDefinitions)</PreProcessorDefinitions>
</ClCompile>
<Lib>
<LinkTimeCodeGeneration>true</LinkTimeCodeGeneration>
</Lib>
<Link>
<ImportLibrary>$(ZoiteChatLib)$(TargetName).lib</ImportLibrary>
<ProgramDatabaseFile>$(ZoiteChatPdb)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>Debug</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View File

@@ -1,7 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio Version 17
VisualStudioVersion = 14.0.25420.1 VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\src\common\common.vcxproj", "{87554B59-006C-4D94-9714-897B27067BA3}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\src\common\common.vcxproj", "{87554B59-006C-4D94-9714-897B27067BA3}"
EndProject EndProject
@@ -201,3 +200,4 @@ Global
{4C0F3940-2EEE-4646-82F7-6CE75B9A72F4} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} {4C0F3940-2EEE-4646-82F7-6CE75B9A72F4} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal