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 \
gettext \
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 \
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 \
patchelf file curl
@@ -41,6 +43,7 @@ jobs:
rm -rf build
meson setup build \
--prefix=/usr \
-Dgtk3=true \
-Dtext-frontend=true \
-Dwith-perl=perl \
-Dwith-python=python3 \
@@ -74,11 +77,9 @@ jobs:
chmod +x linuxdeploy-plugin-gtk
export PATH="${PWD}:${PATH}"
# Bundle CA certificates into the AppDir
install -Dm644 /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'
#!/bin/sh
set -eu
@@ -99,15 +100,26 @@ jobs:
export GIO_EXTRA_MODULES="$APPDIR/usr/lib/gio/modules${GIO_EXTRA_MODULES:+:$GIO_EXTRA_MODULES}"
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_DIR="${SSL_CERT_DIR:-$APPDIR/etc/ssl/certs}"
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" "$@"
EOF
chmod +x AppRun
VERSION="$(git describe --tags --always)"
./linuxdeploy-x86_64.AppImage \

View File

@@ -13,47 +13,36 @@ jobs:
image: debian:bookworm
steps:
- name: Install base tooling (git + deps)
- name: Install packaging tooling and build dependencies
run: |
set -eux
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
git ca-certificates \
build-essential pkg-config meson ninja-build cmake \
gettext \
libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk2.0-dev \
libluajit-5.1-dev libpci-dev libperl-dev libssl-dev \
python3-dev python3-cffi mono-devel desktop-file-utils
build-essential dpkg-dev debhelper fakeroot \
pkg-config meson ninja-build \
gettext iso-codes \
libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk-3-dev libayatana-appindicator3-dev \
liblua5.3-dev libpci-dev libperl-dev libssl-dev \
python3-dev python3-cffi desktop-file-utils
- uses: actions/checkout@v4
with:
submodules: true
- name: Configure
- name: Build Debian packages
run: |
set -eux
rm -rf build
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
dpkg-buildpackage -us -uc -b
- name: Build
- name: Collect Debian artifacts
run: |
set -eux
ninja -C build
mkdir -p artifacts
cp -v ../*.deb ../*.changes ../*.buildinfo artifacts/
- name: Test
run: |
set -eux
ninja -C build test
- name: Install
run: |
set -eux
ninja -C build install
- name: Upload Debian artifacts
uses: actions/upload-artifact@v4
with:
name: zoitechat-debian-packages
path: artifacts/*

View File

@@ -32,7 +32,7 @@ jobs:
git \
meson ninja pkgconf gmake \
gettext-tools \
glib2 gtk+2 dbus-glib libcanberra \
glib2 gtk+3 dbus-glib libcanberra \
luajit mono libgdiplus openssl
work="$(mktemp -d /tmp/zoitechat.XXXXXX)"
@@ -45,6 +45,7 @@ jobs:
meson setup build \
--prefix=/usr/local \
-Dtext-frontend=true \
-Dgtk3=true \
-Dplugin=false \
-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:
windows_build:
runs-on: windows-2019
runs-on: windows-2022
permissions:
contents: read
@@ -20,13 +20,8 @@ jobs:
strategy:
matrix:
platform: [x64, win32]
arch: [x64, x86]
exclude:
- platform: x64
arch: x86
- platform: win32
arch: x64
platform: [x64]
arch: [x64]
fail-fast: false
steps:
@@ -39,16 +34,16 @@ jobs:
- name: Install Dependencies
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
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
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
& 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk
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\x64\release
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
@@ -76,7 +71,7 @@ jobs:
- name: Build
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 }}"
if not exist "%PYTHON_DIR%\libs\python314.lib" (
@@ -93,7 +88,7 @@ jobs:
- name: Preparing Artifacts
run: |
move ..\zoitechat-build\${{ matrix.platform }}\ZoiteChat*.exe .\
move ..\zoitechat-build\${{ matrix.platform }}\ZoiteChat-*.exe .\
move ..\zoitechat-build .\
shell: cmd
@@ -102,7 +97,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: Installer ${{ matrix.arch }}
path: ZoiteChat*.exe
path: ZoiteChat-*.exe
- name: Attest Installer (Artifact Attestation)
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}

View File

@@ -1,6 +1,15 @@
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)
-------------------

View File

@@ -25,6 +25,18 @@
<id>zoitechat.desktop</id>
</provides>
<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">
<description>
<p>Fixes and minor features:</p>

View File

@@ -9,7 +9,7 @@ Terminal=false
Type=Application
Categories=GTK;Network;IRCClient;
StartupNotify=true
StartupWMClass=Zoitechat
StartupWMClass=net.zoite.Zoitechat
X-GNOME-UsesNotifications=true
MimeType=x-scheme-handler/irc;x-scheme-handler/ircs;application/x-zoitechat-theme;application/x-hexchat-theme;
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
* Initial ZoiteChat packaging (forked from HexChat's Debian packaging).

6
debian/control vendored
View File

@@ -9,7 +9,7 @@ Build-Depends:
libcanberra-dev,
libdbus-glib-1-dev,
libglib2.0-dev,
libgtk2.0-dev,
libgtk-3-dev,
liblua5.3-dev,
libpci-dev,
libperl-dev,
@@ -39,8 +39,8 @@ Suggests:
zoitechat-python3,
zoitechat-otr,
unifont
Description: IRC client for GNOME (fork of HexChat 2.17.0 base)
ZoiteChat is a graphical IRC client with a GTK+ GUI. Features include Python,
Description: IRC client for GNOME (fork of HexChat 2.18.0-pre1 base)
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
windows, spell checking, multiple authentication methods including SASL, and
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:
dh_auto_configure -- \
-Dgtk3=true \
-Dinstall-plugin-metainfo=false \
-Dwith-lua=lua53
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/share/applications
usr/share/metainfo/net.zoite.Zoitechat.appdata.xml
usr/share/man/man1/zoitechat.1

View File

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

View File

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

View File

@@ -2,6 +2,9 @@
option('gtk-frontend', type: 'boolean',
description: 'Main graphical interface'
)
option('gtk3', type: 'boolean', value: false,
description: 'Build GTK frontend against GTK 3'
)
option('text-frontend', type: 'boolean', value: false,
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'">
<ClCompile>
<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>
<Link>
<ModuleDefinitionFile>checksum.def</ModuleDefinitionFile>
@@ -41,7 +41,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<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>
<Link>
<ModuleDefinitionFile>checksum.def</ModuleDefinitionFile>

View File

@@ -30,7 +30,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<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>
<Link>
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>
@@ -41,7 +41,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<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>
<Link>
<ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile>

View File

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

View File

@@ -29,7 +29,10 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<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>
</ClCompile>
<Link>
@@ -41,9 +44,12 @@
<Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\zoitechat-plugin.h python.py "$(IntDir)python.c"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<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>
</ClCompile>
<Link>
@@ -67,4 +73,8 @@
<ClCompile Include="$(IntDir)python.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>

View File

@@ -273,3 +273,25 @@ sysinfo_backend_get_network(void)
{
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_network(void);
/*
* Short description of the UI/toolkit + display backend.
* Examples: "GTK3 / Wayland", "GTK2 / X11", "Windows / GTK3".
*/
char *sysinfo_backend_get_ui(void);
#endif

View File

@@ -41,7 +41,7 @@ static zoitechat_plugin *ph;
static char name[] = "Sysinfo";
static char desc[] = "Display info about your hardware and OS";
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
{
@@ -54,11 +54,22 @@ typedef struct
static char *
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[] = {
{"client", "Client", get_client},
{"ui", "UI", sysinfo_backend_get_ui},
{"os", "OS", sysinfo_backend_get_os},
{"cpu", "CPU", sysinfo_backend_get_cpu},
{"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_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);
return 1;
}
@@ -243,6 +255,8 @@ zoitechat_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name, char
int
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_printf (ph, _("%s plugin unloaded\n"), name);
return 1;

View File

@@ -31,7 +31,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<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>
</ClCompile>
<Link>
@@ -44,7 +44,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<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>
</ClCompile>
<Link>
@@ -68,4 +68,4 @@
<ClInclude Include="sysinfo.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>

View File

@@ -18,6 +18,10 @@
*/
#include <glib.h>
#if defined(HAVE_GTK3) || defined(HAVE_GTK2) || defined(HAVE_GTK)
#include <gdk/gdk.h>
#endif
#include "parse.h"
#include "match.h"
#include "sysinfo.h"
@@ -168,3 +172,86 @@ char *sysinfo_backend_get_network(void)
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);
}
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>
<ClCompile>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(OpenSslInclude);$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<ModuleDefinitionFile>winamp.def</ModuleDefinitionFile>

View File

@@ -99,13 +99,13 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<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>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<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>
</ClCompile>
</ItemDefinitionGroup>
@@ -116,8 +116,8 @@
SET SOLUTIONDIR=$(SolutionDir)..\
"$(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"
"$(Python3Path)\python.exe" "$(DepsRoot)\bin\glib-genmarshal" --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 --header "$(ProjectDir)marshalers.list" --output "$(ZoiteChatLib)marshal.h"
$(GlibGenMarshal) --prefix=_zoitechat_marshal --body "$(ProjectDir)marshalers.list" --output "$(ZoiteChatLib)marshal.c"
]]></Command>
</PreBuildEvent>
</ItemDefinitionGroup>

View File

@@ -40,14 +40,11 @@ static GList *contexts = NULL;
static GHashTable *clients = NULL;
static DBusGConnection *connection;
typedef struct RemoteObject RemoteObject;
typedef struct RemoteObjectClass RemoteObjectClass;
G_DECLARE_FINAL_TYPE (RemoteObject, remote_object, REMOTE, OBJECT, GObject)
GType Remote_object_get_type (void);
struct RemoteObject
struct _RemoteObject
{
GObject parent;
GObject parent_instance;
guint last_hook_id;
guint last_list_id;
@@ -59,11 +56,6 @@ struct RemoteObject
void *handle;
};
struct RemoteObjectClass
{
GObjectClass parent;
};
typedef struct
{
guint id;
@@ -89,12 +81,6 @@ enum
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_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++);
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->filename = g_path_get_basename (filename);
remote_object->handle = zoitechat_plugingui_add (ph,
@@ -891,8 +877,8 @@ init_dbus (void)
guint request_name_result;
GError *error = NULL;
dbus_g_object_type_install_info (REMOTE_TYPE_OBJECT,
&dbus_glib_remote_object_object_info);
dbus_g_object_type_install_info (remote_object_get_type (),
&dbus_glib_remote_object_object_info);
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (connection == NULL) {
@@ -930,7 +916,7 @@ init_dbus (void)
G_CALLBACK (name_owner_changed),
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_OBJECT_PATH"/Remote",
G_OBJECT (remote));

View File

@@ -229,7 +229,15 @@ static char *query_wmi (QueryWmiType type)
query = SysAllocString (L"SELECT Name FROM Win32_VideoController");
break;
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;
default:
goto release_queryLanguageName;
@@ -465,7 +473,7 @@ static char *read_hdd_info (IWbemClassObject *object)
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))
{
return NULL;
@@ -580,7 +588,16 @@ static char *zoitechat_strdup_printf (const char *format, ...)
va_start (args, format);
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);
#endif
va_end (args_copy);
if (length < 0)

View File

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

View File

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

View File

@@ -37,6 +37,17 @@
#include "maingui.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 */
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
banlist_opengui (struct session *sess)
{
@@ -818,8 +842,7 @@ banlist_opengui (struct session *sess)
/* create banlist view */
banl->treeview = banlist_treeview_new (vbox, banl);
table = gtk_table_new (1, MODE_CT, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 16);
table = banlist_table_new ();
gtk_box_pack_start (GTK_BOX (vbox), table, 0, 0, 0);
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));
g_signal_connect (G_OBJECT (banl->checkboxes[i]), "toggled",
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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 0);
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"));
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"));
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"));
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);

View File

@@ -45,6 +45,21 @@
#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
{
COL_CHANNEL,
@@ -68,6 +83,102 @@ chanlistrow;
#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
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_signal_connect (G_OBJECT (menu), "selection-done",
G_CALLBACK (chanlist_menu_destroy), NULL);
mg_create_icon_item (_("_Join Channel"), GTK_STOCK_JUMP_TO, menu,
chanlist_join, serv);
mg_create_icon_item (_("_Copy Channel Name"), GTK_STOCK_COPY, menu,
chanlist_copychannel, serv);
mg_create_icon_item (_("Copy _Topic Text"), GTK_STOCK_COPY, menu,
chanlist_copytopic, serv);
{
GtkWidget *item;
item = chanlist_icon_menu_item (_("_Join Channel"), ICON_CHANLIST_JOIN,
G_CALLBACK (chanlist_join), 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);
menu_addfavoritemenu (serv, menu, chan, FALSE);
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;
}
@@ -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);
gtk_table_set_col_spacings (GTK_TABLE (table), 12);
gtk_table_set_row_spacings (GTK_TABLE (table), 3);
#endif
gtk_box_pack_start (GTK_BOX (vbox), table, 0, 1, 0);
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"));
#endif
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_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"));
#endif
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_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..."));
#endif
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_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"));
#endif
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_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
/* ============================================================= */
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_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid);
hbox = gtk_hbox_new (0, 0);
hbox = chanlist_box_new ();
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_FILL, GTK_FILL, 0, 0);
#endif
gtk_widget_show (hbox);
wid = gtk_label_new (_("channels with"));
@@ -860,15 +1055,25 @@ chanlist_opengui (server *serv, int do_refresh)
/* ============================================================= */
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_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid);
hbox = gtk_hbox_new (0, 0);
hbox = chanlist_box_new ();
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_FILL, GTK_FILL, 0, 0);
#endif
gtk_widget_show (hbox);
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:"));
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_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid);
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), _("Regular Expression"));
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_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
g_signal_connect (G_OBJECT (wid), "changed",
G_CALLBACK (chanlist_combo_cb), serv);
gtk_widget_show (wid);
@@ -911,9 +1126,14 @@ chanlist_opengui (server *serv, int do_refresh)
/* ============================================================= */
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_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid);
wid = gtk_entry_new ();
@@ -923,8 +1143,13 @@ chanlist_opengui (server *serv, int do_refresh)
g_signal_connect (G_OBJECT (wid), "activate",
G_CALLBACK (chanlist_search_pressed),
(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_EXPAND | GTK_FILL, 0, 0, 0);
#endif
gtk_widget_show (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 ();
#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_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
#endif
gtk_widget_show (wid);
g_signal_connect (G_OBJECT (serv->gui->chanlist_window), "destroy",

View File

@@ -27,6 +27,13 @@ typedef struct
GtkWidget *b2; /* button2 */
} 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);
/* 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.
* 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)
{
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
{
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)
{
gtk_widget_hide (((tabview *)cv)->b1);
@@ -150,13 +177,13 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv)
if (cv->vertical)
{
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
{
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);
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)
{
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
{
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);
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)
{
GtkWidget *button, *arrow;
#if HAVE_GTK3
const char *icon_name = "pan-end-symbolic";
#endif
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);
#endif
gtk_container_add (GTK_CONTAINER (button), arrow);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
g_signal_connect (G_OBJECT (button), "clicked",
@@ -289,9 +340,13 @@ cv_tabs_init (chanview *cv)
GtkWidget *button;
if (cv->vertical)
outer = gtk_vbox_new (0, 0);
{
outer = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
}
else
outer = gtk_hbox_new (0, 0);
{
outer = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
}
((tabview *)cv)->outer = outer;
g_signal_connect (G_OBJECT (outer), "size_allocate",
G_CALLBACK (cv_tabs_sizealloc), cv);
@@ -308,9 +363,13 @@ cv_tabs_init (chanview *cv)
gtk_widget_show (viewport);
if (cv->vertical)
box = gtk_vbox_new (FALSE, 0);
{
box = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
}
else
box = gtk_hbox_new (FALSE, 0);
{
box = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
}
((tabview *)cv)->inner = box;
gtk_container_add (GTK_CONTAINER (viewport), box);
gtk_widget_show (box);
@@ -318,7 +377,7 @@ cv_tabs_init (chanview *cv)
/* if vertical, the buttons can be side by side */
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_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);
}
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);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_widget_set_can_focus (button, FALSE);
@@ -486,13 +545,21 @@ tab_add_real (chanview *cv, GtkWidget *tab, chan *ch)
if (cv->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 ();
#endif
} else
{
/* 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 ();
#endif
}
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);
gtk_widget_set_hexpand (win, TRUE);
gtk_widget_set_vexpand (win, TRUE);
/*gtk_container_set_border_width (GTK_CONTAINER (win), 1);*/
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_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (cv->box), win);
gtk_widget_show (win);
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");
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]);
gtk_widget_modify_text (view, GTK_STATE_NORMAL, &cv->style->text[GTK_STATE_NORMAL]);
gtk_widget_modify_font (view, cv->style->font_desc);
#if HAVE_GTK3
gtkutil_apply_palette (view, &colors[COL_BG], &colors[COL_FG],
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_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_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_expand (col, TRUE);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
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 */
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 */
int trunc_len;
@@ -109,6 +113,7 @@ chanview_apply_theme (chanview *cv)
{
GtkWidget *w;
treeview *tv;
const PangoFontDescription *font = NULL;
if (cv == NULL)
return;
@@ -122,16 +127,17 @@ chanview_apply_theme (chanview *cv)
return;
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)
{
gtk_widget_modify_base (w, GTK_STATE_NORMAL, &colors[COL_BG]);
gtk_widget_modify_text (w, GTK_STATE_NORMAL, &colors[COL_FG]);
gtkutil_apply_palette (w, &colors[COL_BG], &colors[COL_FG], font);
}
else
{
/* Revert back to theme defaults. */
gtk_widget_modify_base (w, GTK_STATE_NORMAL, NULL);
gtk_widget_modify_text (w, GTK_STATE_NORMAL, NULL);
/* Keep list font in sync while reverting colors to theme defaults. */
gtkutil_apply_palette (w, NULL, NULL, font);
}
}
@@ -294,15 +300,28 @@ chanview_box_destroy_cb (GtkWidget *box, chanview *cv)
chanview *
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;
cv = g_new0 (chanview, 1);
cv->store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_POINTER,
PANGO_TYPE_ATTR_LIST, GDK_TYPE_PIXBUF);
#if HAVE_GTK3
cv->font_desc = font_desc;
#else
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);
#endif
cv->trunc_len = trunc_len;
cv->sorted = sort;
cv->use_icons = use_icons;

View File

@@ -20,10 +20,18 @@
#ifndef ZOITECHAT_CHANVIEW_H
#define ZOITECHAT_CHANVIEW_H
#include "fe-gtk.h"
typedef struct _chanview chanview;
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 (*cb_focus) (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 *
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
@@ -116,70 +120,6 @@ custom_list_sortable_init (GtkTreeSortableIface * iface)
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.
@@ -193,7 +133,6 @@ custom_list_class_init (CustomListClass * klass)
{
GObjectClass *object_class;
parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
object_class = (GObjectClass *) klass;
object_class->finalize = custom_list_finalize;
@@ -265,7 +204,7 @@ custom_list_finalize (GObject * object)
custom_list_clear (CUSTOM_LIST (object));
/* 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>
typedef struct _CustomList CustomList;
typedef struct _CustomListClass CustomListClass;
GType custom_list_get_type (void);
/* Some boilerplate GObject defines. 'klass' is used
@@ -62,20 +65,19 @@ typedef struct
}
chanlistrow;
typedef struct _CustomList CustomList;
typedef struct _CustomListClass CustomListClass;
/* CustomList: this structure contains everything we need for our
* model implementation. You can add extra fields to
* this structure, e.g. hashtables to quickly lookup
* 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. */
struct _CustomList
{
#if HAVE_GTK3
GObject parent_instance;
#else
GObject parent;
#endif
guint num_rows; /* number of rows that we have used */
guint num_alloc; /* number of rows allocated */

View File

@@ -37,6 +37,19 @@
#include "palette.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 */
{
@@ -50,7 +63,7 @@ enum /* DCC SEND/RECV */
COL_ETA,
COL_NICK,
COL_DCC, /* struct DCC * */
COL_COLOR, /* GdkColor */
COL_COLOR, /* PaletteColor */
N_COLUMNS
};
@@ -62,7 +75,7 @@ enum /* DCC CHAT */
CCOL_SENT,
CCOL_START,
CCOL_DCC, /* struct DCC * */
CCOL_COLOR, /* GdkColor * */
CCOL_COLOR, /* PaletteColor * */
CN_COLUMNS
};
@@ -103,6 +116,26 @@ static short view_mode; /* 1=download 2=upload 3=both */
#define VIEW_UPLOAD 2
#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
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);
}
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
dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
gboolean update_only)
@@ -171,11 +227,8 @@ dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
CCOL_SENT, size,
CCOL_START, date,
CCOL_DCC, dcc,
CCOL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1);
dcc_store_color (store, iter, CCOL_COLOR, dccstat[dcc->dccstat].color);
}
static void
@@ -187,8 +240,12 @@ dcc_prepare_row_send (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
float per;
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",
GTK_ICON_SIZE_MENU, NULL);
#endif
/* percentage ack'ed */
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_SPEED, kbs,
COL_ETA, eta,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1);
else
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_NICK, dcc->nick,
COL_DCC, dcc,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1);
dcc_store_color (store, iter, COL_COLOR, dccstat[dcc->dccstat].color);
}
static void
@@ -244,8 +294,12 @@ dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
int to_go;
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",
GTK_ICON_SIZE_MENU, NULL);
#endif
proper_unit (dcc->size, size, sizeof (size));
if (dcc->dccstat == STAT_QUEUED)
@@ -271,10 +325,6 @@ dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
COL_PERC, perc,
COL_SPEED, kbs,
COL_ETA, eta,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1);
else
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_NICK, dcc->nick,
COL_DCC, dcc,
COL_COLOR,
dccstat[dcc->dccstat].color == 1 ?
NULL :
colors + dccstat[dcc->dccstat].color,
-1);
dcc_store_color (store, iter, COL_COLOR, dccstat[dcc->dccstat].color);
}
static gboolean
@@ -730,7 +777,7 @@ dcc_add_column (GtkWidget *tree, int textcol, int colorcol, char *title, gboolea
if (right_justified)
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,
"text", textcol, "foreground-gdk", colorcol,
"text", textcol, PALETTE_FOREGROUND_PROPERTY, colorcol,
NULL);
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);
g_snprintf (buf, sizeof (buf), "<b>%s</b>", text);
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_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);
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_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;
}
@@ -789,7 +854,7 @@ dcc_configure_cb (GtkWindow *win, GdkEventConfigure *event, gpointer data)
int
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;
GSList *group;
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,
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_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);
/* Up/Down Icon column */
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_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);
gtk_table_set_col_spacings (GTK_TABLE (table), 16);
#endif
gtk_box_pack_start (GTK_BOX (vbox), table, 0, 0, 0);
radio = gtk_radio_button_new_with_mnemonic (NULL, _("Both"));
g_signal_connect (G_OBJECT (radio), "toggled",
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);
#endif
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
radio = gtk_radio_button_new_with_mnemonic (group, _("Uploads"));
g_signal_connect (G_OBJECT (radio), "toggled",
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);
#endif
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
radio = gtk_radio_button_new_with_mnemonic (group, _("Downloads"));
g_signal_connect (G_OBJECT (radio), "toggled",
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);
#endif
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);
#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);
gtk_table_set_col_spacings (GTK_TABLE (detailbox), 6);
gtk_table_set_row_spacings (GTK_TABLE (detailbox), 2);
gtk_container_set_border_width (GTK_CONTAINER (detailbox), 6);
#endif
g_signal_connect (G_OBJECT (exp), "activate",
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);
#endif
dccfwin.file_label = dcc_detail_label (_("File:"), detailbox, 0);
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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
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.accept_button = gtkutil_button (bbox, GTK_STOCK_APPLY, 0, accept_clicked, 0, _("Accept"));
dccfwin.resume_button = gtkutil_button (bbox, GTK_STOCK_REFRESH, 0, resume_clicked, 0, _("Resume"));
dccfwin.clear_button = gtkutil_button (bbox, GTK_STOCK_CLEAR, 0, clear_completed, 0, _("Clear"));
dccfwin.abort_button = gtkutil_button (bbox, ICON_DCC_CANCEL, 0, abort_clicked, 0, _("Abort"));
dccfwin.accept_button = gtkutil_button (bbox, ICON_DCC_ACCEPT, 0, accept_clicked, 0, _("Accept"));
dccfwin.resume_button = gtkutil_button (bbox, ICON_DCC_RESUME, 0, resume_clicked, 0, _("Resume"));
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..."));
gtk_widget_set_sensitive (dccfwin.accept_button, FALSE);
gtk_widget_set_sensitive (dccfwin.resume_button, FALSE);
@@ -1036,7 +1163,7 @@ dcc_chat_dclick_cb (GtkTreeView *view, GtkTreePath *path,
int
fe_dcc_open_chat_win (int passive)
{
GtkWidget *view, *vbox, *bbox;
GtkWidget *view, *vbox, *bbox, *scroll;
GtkListStore *store;
char buf[128];
@@ -1056,9 +1183,11 @@ fe_dcc_open_chat_win (int passive)
gtk_box_set_spacing (GTK_BOX (vbox), 3);
store = gtk_list_store_new (CN_COLUMNS, 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_STRING, G_TYPE_STRING,
G_TYPE_POINTER, PALETTE_GDK_TYPE);
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_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_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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
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.accept_button = gtkutil_button (bbox, GTK_STOCK_APPLY, 0, accept_chat_clicked, 0, _("Accept"));
dcccwin.abort_button = gtkutil_button (bbox, ICON_DCC_CANCEL, 0, abort_chat_clicked, 0, _("Abort"));
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.abort_button, FALSE);

View File

@@ -42,6 +42,19 @@
#include "maingui.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
{
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_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);
return view;
@@ -348,19 +361,24 @@ editlist_gui_open (char *title1, char *title2, GSList *list, char *title, char *
if (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 ();
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_container_set_border_width (GTK_CONTAINER (box), 5);
gtk_widget_show (box);
gtkutil_button (box, GTK_STOCK_NEW, 0, editlist_add,
gtkutil_button (box, ICON_EDITLIST_NEW, 0, editlist_add,
NULL, _("Add"));
gtkutil_button (box, GTK_STOCK_DELETE, 0, editlist_delete,
gtkutil_button (box, ICON_EDITLIST_DELETE, 0, editlist_delete,
NULL, _("Delete"));
gtkutil_button (box, GTK_STOCK_CANCEL, 0, editlist_close,
gtkutil_button (box, ICON_EDITLIST_CANCEL, 0, editlist_close,
NULL, _("Cancel"));
gtkutil_button (box, GTK_STOCK_SAVE, 0, editlist_save,
gtkutil_button (box, ICON_EDITLIST_SAVE, 0, editlist_save,
file, _("Save"));
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));

View File

@@ -22,8 +22,11 @@
#include "fe-gtk.h"
#ifdef WIN32
#ifdef GDK_WINDOWING_WIN32
#include <gdk/gdkwin32.h>
#endif
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
@@ -112,6 +115,27 @@ create_msg_dialog (gchar *title, gchar *message)
gtk_dialog_run (GTK_DIALOG (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
int
@@ -120,6 +144,7 @@ fe_args (int argc, char *argv[])
GError *error = NULL;
GOptionContext *context;
char *buffer;
const char *desktop_id = "net.zoite.Zoitechat";
#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
@@ -220,6 +245,8 @@ fe_args (int argc, char *argv[])
}
#ifdef WIN32
win32_set_gsettings_schema_dir ();
/* 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 */
/* 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
g_set_prgname (desktop_id);
#ifndef WIN32
gdk_set_program_class (desktop_id);
#endif
gtk_init (&argc, &argv);
#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);
}
GtkStyle *
create_input_style (GtkStyle *style)
InputStyle *
create_input_style (InputStyle *style)
{
char buf[256];
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);
/* fall back */
@@ -412,27 +462,159 @@ create_input_style (GtkStyle *style)
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 ();
GdkScreen *screen = gdk_screen_get_default ();
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);
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);
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);
#endif
}
#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->base[GTK_STATE_NORMAL] = colors[COL_BG];
style->text[GTK_STATE_NORMAL] = colors[COL_FG];
#endif
return style;
}
@@ -451,7 +633,11 @@ fe_init (void)
gtkosx_application_set_dock_icon_pixbuf (osx_app, pix_zoitechat);
#endif
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 ());
#endif
settings = gtk_settings_get_default ();
if (settings)
@@ -1074,8 +1260,8 @@ fe_gui_info_ptr (session *sess, int info_type)
switch (info_type)
{
case 0: /* native window pointer (for plugins) */
#ifdef WIN32
return gdk_win32_window_get_impl_hwnd (gtk_widget_get_window (sess->gui->window));
#ifdef GDK_WINDOWING_WIN32
return gdk_win32_window_get_handle (gtk_widget_get_window (sess->gui->window));
#else
return sess->gui->window;
#endif

View File

@@ -32,6 +32,22 @@
#include <gtk/gtk.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
#include <gtkosxapplication.h>
#endif
@@ -48,6 +64,15 @@
#define flag_b flag_wid[7]
#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
extern GtkosxApplication *osx_app;
#endif

View File

@@ -30,7 +30,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<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>
</ClCompile>
<Link>
@@ -42,7 +42,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<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>
</ClCompile>
<Link>

View File

@@ -53,6 +53,19 @@
#include "textgui.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);
void key_check_replace_on_change (GtkEditable *editable, gpointer data);
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 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] = {
{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",
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",
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",
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",
@@ -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>i\nInsert in Buffer\nD1:\035\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=<Shift>Page_Down\nChange Selected Nick\nD1!\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))),
"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);
#endif
render = gtk_cell_renderer_accel_new ();
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_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;
}
@@ -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), "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 ();
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_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"));
gtkutil_button (box, GTK_STOCK_DELETE, NULL, key_dialog_delete,
gtkutil_button (box, ICON_FKEYS_DELETE, NULL, key_dialog_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"));
gtkutil_button (box, GTK_STOCK_SAVE, NULL, key_dialog_save,
gtkutil_button (box, ICON_FKEYS_SAVE, NULL, key_dialog_save,
NULL, _("Save"));
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,
char *d2, struct session *sess)
{
int ii, oi, len;
char out[2048], d = 0;
char *out;
if (!d1)
return 0;
len = strlen (d1);
/* 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;
out = g_malloc (strlen (d1) + 1);
key_action_decode_escapes (d1, out);
handle_multiline (sess, out, 0, 0);
g_free (out);
return 0;
}
@@ -1234,13 +1317,19 @@ key_action_insert (GtkWidget * wid, GdkEventKey * evt, char *d1, char *d2,
struct session *sess)
{
int tmp_pos;
char *decoded;
gsize decoded_len;
if (!d1)
return 1;
decoded = g_malloc (strlen (d1) + 1);
decoded_len = key_action_decode_escapes (d1, decoded);
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);
g_free (decoded);
return 2;
}

View File

@@ -62,6 +62,294 @@ struct file_req
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
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;
if (filename == NULL || filename[0] == '\0')
{
fe_message (_("No file selected."), FE_MSG_ERROR);
return;
}
GFile *file = g_file_new_for_path (filename);
if (freq->flags & FRF_WRITE)
@@ -137,10 +431,9 @@ gtkutil_check_file (char *filename, struct file_req *freq)
}
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;
GtkFileChooser *fs = GTK_FILE_CHOOSER (freq->dialog);
if (freq->flags & FRF_MULTIPLE)
{
@@ -165,11 +458,21 @@ gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
else
{
gchar *filename = gtk_file_chooser_get_filename (fs);
gtkutil_check_file (gtk_file_chooser_get_filename (fs), freq);
g_free (filename);
if (filename != NULL)
{
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) */
gtk_widget_destroy (freq->dialog);
}
@@ -177,18 +480,42 @@ gtkutil_file_req_done (GtkWidget * wid, struct file_req *freq)
static void
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);
break;
case GTK_RESPONSE_CANCEL:
/* this should call the "destroy" cb, where we free(freq) */
gtk_widget_destroy (freq->dialog);
return;
}
/* 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
gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *userdata, char *filter, char *extensions,
int flags)
@@ -196,27 +523,124 @@ gtkutil_file_req (GtkWindow *parent, const char *title, void *callback, void *us
struct file_req *freq;
GtkWidget *dialog;
GtkFileFilter *filefilter;
extern char *get_xdir_fs (void);
char *token;
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 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,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
#endif
if (!(flags & FRF_NOASKOVERWRITE))
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
}
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,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
#endif
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];
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));
}
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))
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)
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_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->dialog = dialog;
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_CALLBACK (gtkutil_file_req_destroy), (gpointer) freq);
if (parent)
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
if (effective_parent)
gtk_window_set_transient_for (GTK_WINDOW (dialog), effective_parent);
if (flags & FRF_MODAL)
{
g_assert (parent);
g_assert (effective_parent);
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;
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,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
#endif
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);
@@ -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);
}
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), "ud", userdata);
@@ -450,15 +898,22 @@ fe_get_int (char *msg, int def, void *callback, void *userdata)
GtkAdjustment *adj;
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,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
#endif
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_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), "ud", userdata);
@@ -490,10 +945,17 @@ fe_get_bool (char *title, char *prompt, void *callback, void *userdata)
GtkWidget *prompt_label;
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,
GTK_STOCK_NO, GTK_RESPONSE_REJECT,
GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
NULL);
#endif
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_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)
{
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);
if (box)
gtk_container_add (GTK_CONTAINER (box), wid);
}
else
{
bbox = gtk_hbox_new (0, 0);
bbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
gtk_container_add (GTK_CONTAINER (wid), bbox);
gtk_widget_show (bbox);
img = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
gtk_container_add (GTK_CONTAINER (bbox), img);
gtk_widget_show (img);
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_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);
}
@@ -660,8 +1151,15 @@ gtkutil_treeview_new (GtkWidget *box, GtkTreeModel *model,
win = gtk_scrolled_window_new (0, 0);
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_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);
view = gtk_tree_view_new_with_model (model);
@@ -752,11 +1250,13 @@ gtkutil_treeview_get_selected (GtkTreeView *view, GtkTreeIter *iter_ret, ...)
gboolean
gtkutil_tray_icon_supported (GtkWindow *window)
{
#ifndef GDK_WINDOWING_X11
return TRUE;
#else
#ifdef GDK_WINDOWING_X11
GdkScreen *screen = gtk_window_get_screen (window);
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);
Display *xdisplay = gdk_x11_display_get_xdisplay (display);
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);
return (tray_window != None);
#else
return TRUE;
#endif
}
@@ -805,3 +1307,95 @@ gtkutil_find_font (const char *fontname)
return FALSE;
}
#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 "../common/fe.h"
#include "palette.h"
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_destroy (GtkWidget * igad, GtkWidget * dgad);
void gtkutil_destroy_on_esc (GtkWidget *win);
GtkWidget *gtkutil_button (GtkWidget *box, char *stock, char *tip, void *callback,
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);
GtkWidget *gtkutil_entry_new (int max, GtkWidget * box, void *callback,
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 (GtkTreeView *view, GtkTreeIter *iter_ret, ...);
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__)
gboolean gtkutil_find_font (const char *fontname);

View File

@@ -31,6 +31,17 @@
#include "gtkutil.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
{
MASK_COLUMN,
@@ -360,7 +371,11 @@ ignore_gui_open ()
frame = gtk_frame_new (_("Ignore Stats:"));
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);
#endif
gtk_container_set_border_width (GTK_CONTAINER (stat_box), 6);
gtk_container_add (GTK_CONTAINER (frame), 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);
#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 ();
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_container_set_border_width (GTK_CONTAINER (box), 5);
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..."));
gtkutil_button (box, GTK_STOCK_DELETE, 0, ignore_delete_entry_clicked,
gtkutil_button (box, ICON_IGNORE_DELETE, 0, ignore_delete_entry_clicked,
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"));
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));

View File

@@ -38,6 +38,14 @@
#include "../common/fe.h"
#include "fe-gtk.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
@@ -124,7 +132,6 @@ joind_show_dialog (server *serv)
GtkWidget *hbox2;
GtkWidget *entry1;
GtkWidget *checkbutton1;
GtkWidget *dialog_action_area1;
GtkWidget *okbutton1;
char buf[256];
char buf2[256];
@@ -141,20 +148,26 @@ joind_show_dialog (server *serv)
dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (dialog1));
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_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_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_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);
#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_widget_show (vbox2);
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_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
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);
#endif
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_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
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);
#endif
label = gtk_label_new (_("What would you like to do next?"));
gtk_widget_show (label);
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);
#endif
serv->gui->joind_radio1 = radiobutton1 = gtk_radio_button_new_with_mnemonic (NULL, _("_Nothing, I'll join a channel later."));
gtk_widget_show (radiobutton1);
gtk_box_pack_start (GTK_BOX (vbox2), radiobutton1, FALSE, FALSE, 0);
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_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
@@ -205,7 +233,12 @@ joind_show_dialog (server *serv)
gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
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);
#endif
radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("O_pen the channel list."));
gtk_widget_show (radiobutton3);
@@ -218,7 +251,12 @@ joind_show_dialog (server *serv)
gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
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);
#endif
serv->gui->joind_check = checkbutton1 = gtk_check_button_new_with_mnemonic (_("_Always show this dialog after connecting."));
if (prefs.hex_gui_join_dialog)
@@ -226,13 +264,20 @@ joind_show_dialog (server *serv)
gtk_widget_show (checkbutton1);
gtk_box_pack_start (GTK_BOX (vbox1), checkbutton1, FALSE, FALSE, 0);
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);
okbutton1 = gtk_button_new_from_stock ("gtk-ok");
okbutton1 = gtkutil_button_new_from_stock ("gtk-ok", _("_OK"));
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);
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
#define ZOITECHAT_MAINGUI_H
extern GtkStyle *input_style;
extern InputStyle *input_style;
extern GtkWidget *parent_window;
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;
char *path;
#if HAVE_GTK3
const char *icon_name = NULL;
GtkWidget *box;
GtkWidget *image = NULL;
GtkWidget *label_widget;
#endif
if (!label)
item = gtk_menu_item_new ();
@@ -277,7 +283,6 @@ menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags,
/*if (flags & XCMENU_MARKUP)
item = gtk_image_menu_item_new_with_markup (label);
else*/
item = gtk_image_menu_item_new_with_mnemonic (label);
img = NULL;
if (access (icon, R_OK) == 0) /* try fullpath */
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)
img = gtk_image_new_from_file (path);
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);
#endif
}
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)
gtk_image_menu_item_set_image ((GtkImageMenuItem *)item, img);
#endif
}
else
{
@@ -301,9 +330,20 @@ menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags,
{
item = gtk_menu_item_new_with_label ("");
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);
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);
#endif
}
} else
{
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)
{
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);
#endif
}
else
{
@@ -392,7 +436,11 @@ toggle_cb (GtkWidget *item, char *pref_name)
{
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)
#endif
g_snprintf (buf, sizeof (buf), "set %s 1", pref_name);
else
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_signal_connect (G_OBJECT (menu), "selection-done",
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,
0, event ? event->time : 0);
#endif
}
static void
@@ -695,6 +761,9 @@ void
fe_userlist_update (session *sess, struct User *user)
{
GList *items, *next;
#if HAVE_GTK3
GList *iter;
#endif
if (!nick_submenu || !str_copy)
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);
/* 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;
while (items)
{
@@ -714,6 +794,7 @@ fe_userlist_update (session *sess, struct User *user)
gtk_widget_destroy (items->data);
items = next;
}
#endif
/* and re-create them with new info */
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)
maindone = TRUE;
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)
callback (sess);
}
@@ -1168,8 +1260,22 @@ usermenu_create (GtkWidget *menu)
static void
usermenu_destroy (GtkWidget * menu)
{
GList *items = ((GtkMenuShell *) menu)->children;
GList *items;
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)
{
@@ -1177,6 +1283,7 @@ usermenu_destroy (GtkWidget * menu)
gtk_widget_destroy (items->data);
items = next;
}
#endif
}
void
@@ -1387,7 +1494,11 @@ menu_join_cb (GtkWidget *dialog, gint response, GtkEntry *entry)
switch (response)
{
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);
#endif
break;
case GTK_RESPONSE_HELP:
@@ -1408,19 +1519,59 @@ static void
menu_join (GtkWidget * wid, gpointer none)
{
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"),
GTK_WINDOW (parent_window), 0,
_("Retrieve channel list"), GTK_RESPONSE_HELP,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
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);
#endif
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 ();
#if HAVE_GTK3
gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE); /* avoid auto-selection */
#else
GTK_ENTRY (entry)->editable = 0; /* avoid auto-selection */
#endif
gtk_entry_set_text (GTK_ENTRY (entry), "#");
g_signal_connect (G_OBJECT (entry), "activate",
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_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);
#endif
gtk_widget_show_all (dialog);
@@ -1655,7 +1810,11 @@ static void
menu_layout_cb (GtkWidget *item, gpointer none)
{
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)
#endif
prefs.hex_gui_tab_layout = 0;
menu_change_layout ();
@@ -1670,7 +1829,11 @@ menu_apply_metres_cb (session *sess)
static void
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)
#endif
{
prefs.hex_gui_lagometer = 0;
prefs.hex_gui_throttlemeter = 0;
@@ -1682,7 +1845,11 @@ menu_metres_off (GtkWidget *item, gpointer none)
static void
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)
#endif
{
prefs.hex_gui_lagometer = 2;
prefs.hex_gui_throttlemeter = 2;
@@ -1694,7 +1861,11 @@ menu_metres_text (GtkWidget *item, gpointer none)
static void
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)
#endif
{
prefs.hex_gui_lagometer = 1;
prefs.hex_gui_throttlemeter = 1;
@@ -1706,7 +1877,11 @@ menu_metres_graph (GtkWidget *item, gpointer none)
static void
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)
#endif
{
prefs.hex_gui_lagometer = 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_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_label (dialog, "Website");
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));
}
#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[] = {
{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},
{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_("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},
@@ -1784,14 +2000,14 @@ static struct mymenu mymenu[] = {
{0, 0, 0, M_END, 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 */
#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)
{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},
{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},
#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_("_Server"), 0, 0, M_NEWMENU, 0, 0, 1},
{N_("_Disconnect"), menu_disconnect, GTK_STOCK_DISCONNECT, M_MENUSTOCK, MENU_ID_DISCONNECT, 0, 1},
{N_("_Reconnect"), menu_reconnect, GTK_STOCK_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_("Channel _List"), menu_chanlist, GTK_STOCK_INDEX, M_MENUITEM, 0, 0, 1},
{N_("_Disconnect"), menu_disconnect, ICON_DISCONNECT, M_MENUSTOCK, MENU_ID_DISCONNECT, 0, 1},
{N_("_Reconnect"), menu_reconnect, ICON_CONNECT, M_MENUSTOCK, MENU_ID_RECONNECT, 0, 1},
{N_("_Join a Channel" ELLIPSIS), menu_join, ICON_JOIN, M_MENUSTOCK, MENU_ID_JOIN, 0, 1},
{N_("Channel _List"), menu_chanlist, ICON_CHANLIST, M_MENUITEM, 0, 0, 1},
{0, 0, 0, M_SEP, 0, 0, 0},
#define AWAY_OFFSET (41)
{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_("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},
{N_("Auto Replace"), menu_rpopup, 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_("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_("C_lear Text"), menu_flushbuffer, GTK_STOCK_CLEAR, M_MENUSTOCK, 0, 0, 1},
{N_("Save Text" ELLIPSIS), menu_savebuffer, GTK_STOCK_SAVE, M_MENUSTOCK, 0, 0, 1},
{N_("C_lear Text"), menu_flushbuffer, ICON_CLEAR, M_MENUSTOCK, 0, 0, 1},
{N_("Save Text" ELLIPSIS), menu_savebuffer, ICON_SAVE, M_MENUSTOCK, 0, 0, 1},
#define SEARCH_OFFSET (70)
{N_("Search"), 0, GTK_STOCK_JUSTIFY_LEFT, M_MENUSUB, 0, 0, 1},
{N_("Search Text" ELLIPSIS), menu_search, GTK_STOCK_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 Previous" ), menu_search_prev, GTK_STOCK_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_G},
{N_("Search"), 0, ICON_SEARCH, M_MENUSUB, 0, 0, 1},
{N_("Search Text" ELLIPSIS), menu_search, ICON_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_f},
{N_("Search Next" ), menu_search_next, ICON_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},
{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_("_About"), menu_about, GTK_STOCK_ABOUT, M_MENUSTOCK, 0, 0, 1},
{N_("_Contents"), menu_docs, ICON_HELP, M_MENUSTOCK, 0, 0, 1, GDK_KEY_F1},
{N_("_About"), menu_about, ICON_ABOUT, M_MENUSTOCK, 0, 0, 1},
{0, 0, 0, M_END, 0, 0, 0},
};
@@ -1893,15 +2109,56 @@ menu_set_fullscreen (session_gui *gui, int full)
GtkWidget *
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 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);
#endif
}
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));
#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);
gtk_image_menu_item_set_image ((GtkImageMenuItem *)item, img);
gtk_widget_show (img);
#endif
return item;
}
@@ -1920,30 +2177,71 @@ menu_canacaccel (GtkWidget *widget, guint signal_id, gpointer user_data)
static GtkMenuItem *
menu_find_item (GtkWidget *menu, char *name)
{
GList *items = ((GtkMenuShell *) menu)->children;
GList *items;
#if HAVE_GTK3
GList *items_head;
#endif
GtkMenuItem *item;
GtkWidget *child;
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)
{
item = items->data;
#if HAVE_GTK3
child = gtk_bin_get_child (GTK_BIN (item));
#else
child = GTK_BIN (item)->child;
#endif
if (child) /* separators arn't labels, skip them */
{
labeltext = g_object_get_data (G_OBJECT (item), "name");
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))
return item;
{
found = item;
break;
}
} else if (name == NULL)
{
return item;
found = item;
break;
}
items = items->next;
}
#if HAVE_GTK3
g_list_free (items_head);
#endif
return NULL;
return found;
}
static GtkWidget *
@@ -2025,7 +2323,11 @@ menu_update_cb (GtkWidget *menu, menu_entry *me, char *target)
gtk_widget_set_sensitive (item, me->enable);
/* must do it without triggering the callback */
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;
#endif
}
}
@@ -2034,7 +2336,11 @@ static void
menu_radio_cb (GtkCheckMenuItem *item, menu_entry *me)
{
me->state = 0;
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (item))
#else
if (item->active)
#endif
me->state = 1;
/* update the state, incase this was changed via right-click. */
@@ -2050,7 +2356,11 @@ static void
menu_toggle_cb (GtkCheckMenuItem *item, menu_entry *me)
{
me->state = 0;
#if HAVE_GTK3
if (gtk_check_menu_item_get_active (item))
#else
if (item->active)
#endif
me->state = 1;
/* update the state, incase this was changed via right-click. */
@@ -2092,7 +2402,17 @@ menu_reorder (GtkMenu *menu, GtkWidget *item, int pos)
return;
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);
#endif
else
gtk_menu_reorder_child (menu, item, pos);
}
@@ -2158,7 +2478,17 @@ menu_add_sub (GtkWidget *menu, menu_entry *me)
{
pos = me->pos;
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;
#endif
menu_quick_sub (me->label, menu, &item, me->markup ? XCMENU_MARKUP|XCMENU_MNEMONIC : XCMENU_MNEMONIC, pos);
}
return item;
@@ -2436,7 +2766,11 @@ normalitem:
item = gtk_check_menu_item_new_with_mnemonic (_(mymenu[i].text));
togitem:
/* 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;
#endif
/*gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
mymenu[i].state);*/
if (mymenu[i].key != 0)

View File

@@ -28,18 +28,50 @@ zoitechat_gtk_sources = [
'xtext.c'
]
gtk_dep = dependency('gtk+-2.0', version: '>= 2.24.0')
zoitechat_gtk_cflags = []
zoitechat_gtk_deps = [
zoitechat_common_dep,
libgmodule_dep, # used by libsexy
gtk_dep
]
if gtk_dep.get_pkgconfig_variable('target') == 'x11'
zoitechat_gtk_deps += dependency('x11')
if get_option('gtk3')
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
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 = []

View File

@@ -37,6 +37,19 @@
#include "palette.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 */
enum
@@ -64,7 +77,7 @@ notify_closegui (void)
}
/* 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
notify_treecell_property_mapper (GtkTreeViewColumn *col, GtkCellRenderer *cell,
@@ -72,17 +85,44 @@ notify_treecell_property_mapper (GtkTreeViewColumn *col, GtkCellRenderer *cell,
gpointer data)
{
gchar *text;
GdkColor *colour;
PaletteColor *colour;
int model_column = GPOINTER_TO_INT (data);
gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
COLOUR_COLUMN, &colour,
model_column, &text, -1);
g_object_set (G_OBJECT (cell), "text", text, NULL);
g_object_set (G_OBJECT (cell), "foreground-gdk", colour, NULL);
#if HAVE_GTK3
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);
}
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
notify_row_cb (GtkTreeSelection *sel, GtkTreeView *view)
{
@@ -105,6 +145,7 @@ notify_treeview_new (GtkWidget *box)
{
GtkListStore *store;
GtkWidget *view;
GtkWidget *scroll;
GtkTreeViewColumn *col;
int col_id;
@@ -113,7 +154,7 @@ notify_treeview_new (GtkWidget *box)
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_POINTER, /* can't specify colour! */
PALETTE_GDK_TYPE,
G_TYPE_POINTER
);
g_return_val_if_fail (store != NULL, NULL);
@@ -124,6 +165,8 @@ notify_treeview_new (GtkWidget *box)
STATUS_COLUMN, _("Status"),
SERVER_COLUMN, _("Network"),
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);
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 */
gtk_list_store_append (store, &iter);
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)
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 */
gtk_list_store_append (store, &iter);
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)
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];
dialog = gtk_dialog_new_with_buttons (msg, NULL, 0,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
LABEL_NOTIFY_CANCEL, GTK_RESPONSE_REJECT,
LABEL_NOTIFY_OK, GTK_RESPONSE_ACCEPT,
NULL);
if (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);
table = gtk_table_new (2, 3, FALSE);
table = gtkutil_grid_new (2, 3, FALSE);
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_col_spacings (GTK_TABLE (table), 8);
#endif
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), table);
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 ();
gtk_entry_set_text (GTK_ENTRY (entry), nick);
g_signal_connect (G_OBJECT (entry), "activate",
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_CALLBACK (notifygui_add_cb), entry);
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 ();
g_object_set_data (G_OBJECT (entry), "net", wid);
g_signal_connect (G_OBJECT (wid), "activate",
G_CALLBACK (notifygui_add_enter), dialog);
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);
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_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);
}
@@ -415,17 +465,22 @@ notify_opengui (void)
view = notify_treeview_new (vbox);
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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
gtk_box_pack_end (GTK_BOX (vbox), bbox, 0, 0, 0);
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..."));
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"));
notify_button_opendialog =

View File

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

View File

@@ -24,7 +24,31 @@
#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_BG 33
@@ -43,8 +67,8 @@ void palette_load (void);
void palette_save (void);
/* 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_dark_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 PaletteColor *col);
/*
* Apply ZoiteChat's built-in "dark mode" palette.

View File

@@ -31,18 +31,39 @@
#include "menu.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
#include <unistd.h>
#endif
typedef enum /* current icon status */
{
TS_NONE,
TS_MESSAGE,
TS_HIGHLIGHT,
TS_FILEOFFER,
TS_CUSTOM /* plugin */
} TrayStatus;
TRAY_ICON_NONE,
TRAY_ICON_NORMAL,
TRAY_ICON_MESSAGE,
TRAY_ICON_HIGHLIGHT,
TRAY_ICON_FILEOFFER,
TRAY_ICON_CUSTOM1,
TRAY_ICON_CUSTOM2
} TrayIconState;
typedef enum
{
@@ -51,7 +72,37 @@ typedef enum
WS_HIDDEN
} 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* TrayCustomIcon;
#define tray_icon_from_file(f) gdk_pixbuf_new_from_file(f,NULL)
#define tray_icon_free(i) g_object_unref(i)
@@ -59,19 +110,59 @@ typedef GdkPixbuf* TrayIcon;
#define ICON_MSG pix_tray_message
#define ICON_HILIGHT pix_tray_highlight
#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
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 TrayStatus tray_status;
#ifdef WIN32
static TrayIconState tray_icon_state;
static TrayIcon tray_flash_icon;
static TrayIconState tray_flash_state;
#if defined(WIN32)
static guint tray_menu_timer;
static gint64 tray_menu_inactivetime;
#endif
static zoitechat_plugin *ph;
static TrayIcon custom_icon1;
static TrayIcon custom_icon2;
static TrayCustomIcon custom_icon1;
static TrayCustomIcon custom_icon2;
static int tray_priv_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_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);
static gboolean tray_menu_try_restore (void);
static void tray_cleanup (void);
static void tray_init (void);
if (!filename)
return NULL;
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
tray_get_window_status (void)
@@ -136,11 +616,27 @@ tray_count_networks (void)
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
fe_tray_set_tooltip (const char *text)
{
if (sticon)
gtk_status_icon_set_tooltip_text (sticon, text);
if (!tray_backend_active)
return;
tray_backend_set_tooltip (text);
}
static void
@@ -168,9 +664,9 @@ tray_stop_flash (void)
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 ();
chans = tray_count_channels ();
if (nets)
@@ -192,7 +688,8 @@ tray_stop_flash (void)
custom_icon2 = NULL;
}
tray_status = TS_NONE;
tray_flash_icon = NULL;
tray_flash_state = TRAY_ICON_NONE;
}
static void
@@ -205,40 +702,42 @@ tray_reset_counts (void)
}
static int
tray_timeout_cb (TrayIcon icon)
tray_timeout_cb (gpointer userdata)
{
(void)userdata;
if (custom_icon1)
{
if (gtk_status_icon_get_pixbuf (sticon) == custom_icon1)
if (tray_icon_state == TRAY_ICON_CUSTOM1)
{
if (custom_icon2)
gtk_status_icon_set_from_pixbuf (sticon, custom_icon2);
tray_set_custom_icon_state (custom_icon2, TRAY_ICON_CUSTOM2);
else
gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL);
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
}
else
{
gtk_status_icon_set_from_pixbuf (sticon, custom_icon1);
tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
}
}
else
{
if (gtk_status_icon_get_pixbuf (sticon) == ICON_NORMAL)
gtk_status_icon_set_from_pixbuf (sticon, icon);
if (tray_icon_state == TRAY_ICON_NORMAL)
tray_set_icon_state (tray_flash_icon, tray_flash_state);
else
gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL);
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
}
return 1;
}
static void
tray_set_flash (TrayIcon icon)
tray_set_flash (TrayIcon icon, TrayIconState state)
{
if (!sticon)
if (!tray_backend_active)
return;
/* already flashing the same icon */
if (flash_tag && gtk_status_icon_get_pixbuf (sticon) == icon)
if (flash_tag && tray_icon_state == state)
return;
/* no flashing if window is focused */
@@ -247,16 +746,18 @@ tray_set_flash (TrayIcon icon)
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)
flash_tag = g_timeout_add (TIMEOUT, (GSourceFunc) tray_timeout_cb, icon);
flash_tag = g_timeout_add (TIMEOUT, (GSourceFunc) tray_timeout_cb, NULL);
}
void
fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
{
tray_apply_setup ();
if (!sticon)
if (!tray_backend_active)
return;
tray_stop_flash ();
@@ -268,16 +769,15 @@ fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
if (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);
tray_status = TS_CUSTOM;
}
void
fe_tray_set_icon (feicon icon)
{
tray_apply_setup ();
if (!sticon)
if (!tray_backend_active)
return;
tray_stop_flash ();
@@ -288,13 +788,13 @@ fe_tray_set_icon (feicon icon)
break;
case FE_ICON_MESSAGE:
case FE_ICON_PRIVMSG:
tray_set_flash (ICON_MSG);
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
break;
case FE_ICON_HIGHLIGHT:
tray_set_flash (ICON_HILIGHT);
tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
break;
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)
{
tray_apply_setup ();
if (!sticon)
if (!tray_backend_active)
return;
tray_stop_flash ();
@@ -310,8 +810,7 @@ fe_tray_set_file (const char *filename)
if (filename)
{
custom_icon1 = tray_icon_from_file (filename);
gtk_status_icon_set_from_pixbuf (sticon, custom_icon1);
tray_status = TS_CUSTOM;
tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
}
}
@@ -324,7 +823,7 @@ tray_toggle_visibility (gboolean force_hide)
static int fullscreen;
GtkWindow *win;
if (!sticon)
if (!tray_backend_active)
return FALSE;
/* ph may have an invalid context now */
@@ -369,15 +868,22 @@ tray_toggle_visibility (gboolean force_hide)
static void
tray_menu_restore_cb (GtkWidget *item, gpointer userdata)
{
(void)item;
(void)userdata;
tray_toggle_visibility (FALSE);
}
static void
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);
}
@@ -403,6 +909,9 @@ tray_menu_try_restore (void)
static void
tray_menu_quit_cb (GtkWidget *item, gpointer userdata)
{
(void)item;
(void)userdata;
mg_open_quit_dialog (FALSE);
}
@@ -483,6 +992,8 @@ blink_item (unsigned int *setting, GtkWidget *menu, char *label)
static void
tray_menu_destroy (GtkWidget *menu, gpointer userdata)
{
(void)userdata;
gtk_widget_destroy (menu);
g_object_unref (menu);
#ifdef WIN32
@@ -494,6 +1005,8 @@ tray_menu_destroy (GtkWidget *menu, gpointer userdata)
static gboolean
tray_menu_enter_cb (GtkWidget *menu)
{
(void)menu;
tray_menu_inactivetime = 0;
return FALSE;
}
@@ -501,6 +1014,8 @@ tray_menu_enter_cb (GtkWidget *menu)
static gboolean
tray_menu_left_cb (GtkWidget *menu)
{
(void)menu;
tray_menu_inactivetime = g_get_real_time ();
return FALSE;
}
@@ -521,14 +1036,16 @@ tray_check_hide (GtkWidget *menu)
static void
tray_menu_settings (GtkWidget * wid, gpointer none)
{
(void)wid;
(void)none;
extern void setup_open (void);
setup_open ();
}
static void
tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
tray_menu_populate (GtkWidget *menu)
{
static GtkWidget *menu;
GtkWidget *submenu;
GtkWidget *item;
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 */
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)
tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL);
else
@@ -574,59 +1082,96 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
menu_add_plugin_items (menu, "\x5$TRAY", 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);
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_sink (menu);
g_object_unref (menu);
g_signal_connect (G_OBJECT (menu), "selection-done",
G_CALLBACK (tray_menu_destroy), NULL);
G_CALLBACK (tray_menu_destroy), NULL);
#ifdef WIN32
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_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);
#endif
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL,
userdata, button, time);
userdata, button, time);
}
#endif
static void
tray_init (void)
{
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_icon2 = NULL;
sticon = gtk_status_icon_new_from_pixbuf (ICON_NORMAL);
if (!sticon)
if (!tray_backend_init ())
return;
g_signal_connect (G_OBJECT (sticon), "popup-menu",
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);
tray_icon_state = TRAY_ICON_NORMAL;
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
}
static int
tray_hilight_cb (char *word[], void *userdata)
{
/*if (tray_status == TS_HIGHLIGHT)
/*if (tray_icon_state == TRAY_ICON_HIGHLIGHT)
return ZOITECHAT_EAT_NONE;*/
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 */
tray_hilight_count++;
@@ -645,12 +1190,12 @@ tray_hilight_cb (char *word[], void *userdata)
static int
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;
if (prefs.hex_input_tray_chans)
{
tray_set_flash (ICON_MSG);
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
tray_pub_count++;
if (tray_pub_count == 1)
@@ -677,7 +1222,7 @@ tray_priv (char *from, char *text)
if (prefs.hex_input_tray_priv)
{
tray_set_flash (ICON_MSG);
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
tray_priv_count++;
if (tray_priv_count == 1)
@@ -711,7 +1256,7 @@ tray_dcc_cb (char *word[], void *userdata)
{
const char *network;
/* if (tray_status == TS_FILEOFFER)
/* if (tray_icon_state == TRAY_ICON_FILEOFFER)
return ZOITECHAT_EAT_NONE;*/
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))
{
tray_set_flash (ICON_FILE);
tray_set_flash (ICON_FILE, TRAY_ICON_FILEOFFER);
tray_file_count++;
if (tray_file_count == 1)
@@ -747,17 +1292,14 @@ tray_cleanup (void)
{
tray_stop_flash ();
if (sticon)
{
g_object_unref ((GObject *)sticon);
sticon = NULL;
}
if (tray_backend_active)
tray_backend_cleanup ();
}
void
tray_apply_setup (void)
{
if (sticon)
if (tray_backend_active)
{
if (!prefs.hex_gui_tray)
tray_cleanup ();

View File

@@ -48,6 +48,54 @@ enum
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 *
plugingui_treeview_new (GtkWidget *box)
@@ -120,21 +168,27 @@ fe_pluginlist_update (void)
return;
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));
if (!GTK_IS_LIST_STORE (store))
return;
gtk_list_store_clear (store);
list = plugin_list;
while (list)
{
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_set (store, &iter, NAME_COLUMN, pl->name,
VERSION_COLUMN, pl->version,
FILE_COLUMN, file_part (pl->filename),
DESC_COLUMN, pl->desc,
FILEPATH_COLUMN, pl->filename, -1);
gtk_list_store_set (store, &iter, NAME_COLUMN, plugingui_safe_string (pl->name),
VERSION_COLUMN, plugingui_safe_string (pl->version),
FILE_COLUMN, pl->filename ? file_part (pl->filename) : "",
DESC_COLUMN, plugingui_safe_string (pl->desc),
FILEPATH_COLUMN, plugingui_safe_string (pl->filename), -1);
}
list = list->next;
}
@@ -143,15 +197,36 @@ fe_pluginlist_update (void)
static void
plugingui_load_cb (session *sess, char *file)
{
session *target_sess;
if (file)
{
char *buf;
char *load_target;
if (strchr (file, ' '))
buf = g_strdup_printf ("LOAD \"%s\"", file);
target_sess = is_session (sess) ? sess : current_sess;
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
buf = g_strdup_printf ("LOAD %s", file);
handle_command (sess, buf, FALSE);
buf = g_strdup_printf ("LOAD %s", load_target);
handle_command (target_sess, buf, FALSE);
g_free (load_target);
g_free (buf);
}
}
@@ -159,12 +234,15 @@ plugingui_load_cb (session *sess, char *file)
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,
sub_dir, "*."PLUGIN_SUFFIX";*.lua;*.pl;*.py;*.tcl;*.js", FRF_FILTERISINITIAL|FRF_EXTENSIONS);
if (xdir && xdir[0] != '\0')
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
@@ -177,6 +255,7 @@ static void
plugingui_unload (GtkWidget * wid, gpointer unused)
{
char *modname, *file;
session *target_sess;
GtkTreeView *view;
GtkTreeIter iter;
@@ -184,6 +263,18 @@ plugingui_unload (GtkWidget * wid, gpointer unused)
if (!gtkutil_treeview_get_selected (view, &iter, NAME_COLUMN, &modname,
FILEPATH_COLUMN, &file, -1))
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))
{
@@ -194,11 +285,19 @@ plugingui_unload (GtkWidget * wid, gpointer unused)
{
char *buf;
/* 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, ' '))
buf = g_strdup_printf ("UNLOAD \"%s\"", file);
else
buf = g_strdup_printf ("UNLOAD %s", file);
handle_command (current_sess, buf, FALSE);
handle_command (target_sess, buf, FALSE);
g_free (buf);
}
@@ -210,16 +309,24 @@ static void
plugingui_reloadbutton_cb (GtkWidget *wid, GtkTreeView *view)
{
char *file = plugingui_getfilename(view);
session *target_sess;
if (file)
{
char *buf;
target_sess = plugingui_get_target_session ();
if (!target_sess)
{
g_free (file);
return;
}
if (strchr (file, ' '))
buf = g_strdup_printf ("RELOAD \"%s\"", file);
else
buf = g_strdup_printf ("RELOAD %s", file);
handle_command (current_sess, buf, FALSE);
handle_command (target_sess, buf, FALSE);
g_free (buf);
g_free (file);
}
@@ -229,6 +336,7 @@ void
plugingui_open (void)
{
GtkWidget *view;
GtkWidget *view_scroll;
GtkWidget *vbox, *hbox;
char buf[128];
@@ -244,22 +352,46 @@ plugingui_open (void)
gtkutil_destroy_on_esc (plugin_window);
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);
#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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
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..."));
gtkutil_button (hbox, GTK_STOCK_DELETE, NULL,
gtkutil_button (hbox, ICON_PLUGIN_UNLOAD, NULL,
plugingui_unload, NULL, _("_Unload"));
gtkutil_button (hbox, GTK_STOCK_REFRESH, NULL,
gtkutil_button (hbox, ICON_PLUGIN_RELOAD, NULL,
plugingui_reloadbutton_cb, view, _("_Reload"));
#endif
fe_pluginlist_update ();

View File

@@ -42,6 +42,15 @@
#include "xtext.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
close_rawlog (GtkWidget *wid, server *serv)
{
@@ -119,7 +128,13 @@ open_rawlog (struct server *serv)
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_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);
#endif
palette_get_xtext_colors (xtext_palette, XTEXT_COLS);
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 (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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
#endif
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"));
gtkutil_button (bbox, GTK_STOCK_SAVE_AS, NULL, rawlog_savebutton,
gtkutil_button (bbox, ICON_RAWLOG_SAVE_AS, NULL, rawlog_savebutton,
serv, _("Save As..."));
/* 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_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
# define DEFAULT_SERVER "newserver/6697"
#else
@@ -92,6 +107,22 @@ static session *servlist_sess;
static void servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data);
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[]=
{
@@ -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 *
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);
g_signal_connect (G_OBJECT (but), "toggled",
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);
return but;
@@ -1276,8 +1377,16 @@ servlist_create_entry (GtkWidget *table, char *labeltext, int row,
if (label_ret)
*label_ret = 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);
#endif
entry = gtk_entry_new ();
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_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;
}
@@ -1563,14 +1675,24 @@ servlist_username_changed_cb (GtkEntry *entry, gpointer userdata)
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);
#endif
gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY,
_("User name cannot be left blank."));
gtk_widget_set_sensitive (connect_btn, FALSE);
}
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);
#endif
gtk_widget_set_sensitive (connect_btn, TRUE);
}
}
@@ -1585,22 +1707,38 @@ servlist_nick_changed_cb (GtkEntry *entry, gpointer userdata)
if (!nick1[0] || !nick2[0])
{
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);
#endif
gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY,
_("You cannot have an empty nick name."));
gtk_widget_set_sensitive (connect_btn, FALSE);
}
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);
#endif
gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY,
_("You must have two unique nick names."));
gtk_widget_set_sensitive (connect_btn, FALSE);
}
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_nick2), GTK_ENTRY_ICON_SECONDARY, NULL);
#endif
gtk_widget_set_sensitive (connect_btn, TRUE);
}
}
@@ -1680,7 +1818,12 @@ bold_label (char *text)
g_snprintf (buf, sizeof (buf), "<b>%s</b>", text);
label = gtk_label_new (buf);
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);
#endif
gtk_widget_show (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_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);
/* 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);
scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
@@ -1845,18 +1988,32 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
/* Button Box */
#if HAVE_GTK3
vbuttonbox1 = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
#elif !HAVE_GTK3
vbuttonbox1 = gtk_vbutton_box_new ();
#endif
gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3);
gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
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_CALLBACK (servlist_addbutton_cb), notebook);
gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonadd);
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_CALLBACK (servlist_deletebutton_cb), notebook);
gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonremove);
@@ -1870,10 +2027,15 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
/* 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);
#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_col_spacings (GTK_TABLE (table3), 8);
#endif
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."));
@@ -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);
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);
#endif
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."));
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);
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);
#endif
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 */
#if HAVE_GTK3
hseparator2 = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
#elif !HAVE_GTK3
hseparator2 = gtk_hseparator_new ();
#endif
gtk_box_pack_start (GTK_BOX (vbox5), hseparator2, FALSE, FALSE, 8);
hbuttonbox4 = gtk_hbutton_box_new ();
gtk_box_pack_start (GTK_BOX (vbox5), hbuttonbox4, FALSE, FALSE, 0);
#if HAVE_GTK3
hbuttonbox4 = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
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_CALLBACK (servlist_edit_close_cb), 0);
gtk_container_add (GTK_CONTAINER (hbuttonbox4), button10);
@@ -1994,82 +2192,115 @@ servlist_open_networks (void)
if (current_sess)
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_container_add (GTK_CONTAINER (servlist), vbox1);
label2 = bold_label (_("User Information"));
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_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
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_col_spacings (GTK_TABLE (table1), 4);
#endif
label3 = gtk_label_new_with_mnemonic (_("_Nick name:"));
gtk_widget_show (label3);
gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, label3, 0, 1, 0, 1,
FALSE, FALSE,
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);
#endif
label4 = gtk_label_new (_("Second choice:"));
gtk_widget_show (label4);
gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, label4, 0, 1, 1, 2,
FALSE, FALSE,
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);
#endif
label5 = gtk_label_new (_("Third choice:"));
gtk_widget_show (label5);
gtk_table_attach (GTK_TABLE (table1), label5, 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, label5, 0, 1, 2, 3,
FALSE, FALSE,
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);
#endif
label6 = gtk_label_new_with_mnemonic (_("_User name:"));
gtk_widget_show (label6);
gtk_table_attach (GTK_TABLE (table1), label6, 0, 1, 3, 4,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, label6, 0, 1, 3, 4,
FALSE, FALSE,
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);
#endif
/* label7 = gtk_label_new_with_mnemonic (_("Rea_l name:"));
gtk_widget_show (label7);
gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 4, 5,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);*/
*/
entry_nick1 = entry1 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry1), prefs.hex_irc_nick1);
gtk_widget_show (entry1);
gtk_table_attach (GTK_TABLE (table1), entry1, 1, 2, 0, 1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, entry1, 1, 2, 0, 1,
TRUE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
entry_nick2 = entry2 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry2), prefs.hex_irc_nick2);
gtk_widget_show (entry2);
gtk_table_attach (GTK_TABLE (table1), entry2, 1, 2, 1, 2,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, entry2, 1, 2, 1, 2,
TRUE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
entry_nick3 = entry3 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry3), prefs.hex_irc_nick3);
gtk_widget_show (entry3);
gtk_table_attach (GTK_TABLE (table1), entry3, 1, 2, 2, 3,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, entry3, 1, 2, 2, 3,
TRUE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
entry_guser = entry4 = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry4), prefs.hex_irc_user_name);
gtk_widget_show (entry4);
gtk_table_attach (GTK_TABLE (table1), entry4, 1, 2, 3, 4,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
servlist_table_attach (table1, entry4, 1, 2, 3, 4,
TRUE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
/* entry_greal = entry5 = gtk_entry_new ();
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) (0), 0, 0); */
vbox2 = gtk_vbox_new (FALSE, 0);
vbox2 = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
gtk_widget_show (vbox2);
gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0);
label1 = bold_label (_("Networks"));
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_box_pack_start (GTK_BOX (vbox2), table4, TRUE, TRUE, 0);
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_col_spacings (GTK_TABLE (table4), 3);
#endif
scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolledwindow3);
gtk_table_attach (GTK_TABLE (table4), scrolledwindow3, 0, 1, 0, 1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
servlist_table_attach (table4, scrolledwindow3, 0, 1, 0, 1,
TRUE, TRUE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_FILL,
0, 0);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3),
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow3),
@@ -2123,10 +2360,11 @@ servlist_open_networks (void)
"weight", 2,
NULL);
hbox = gtk_hbox_new (0, FALSE);
gtk_table_attach (GTK_TABLE (table4), hbox, 0, 2, 1, 2,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
hbox = gtkutil_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 0);
servlist_table_attach (table4, hbox, 0, 2, 1, 2,
FALSE, FALSE,
SERVLIST_ALIGN_FILL, SERVLIST_ALIGN_CENTER,
0, 0);
gtk_widget_show (hbox);
checkbutton_skip =
@@ -2147,22 +2385,37 @@ servlist_open_networks (void)
G_CALLBACK (fav_servlist), 0);
gtk_widget_show (checkbutton_fav);
#if HAVE_GTK3
vbuttonbox2 = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
#elif !HAVE_GTK3
vbuttonbox2 = gtk_vbutton_box_new ();
#endif
gtk_box_set_spacing (GTK_BOX (vbuttonbox2), 3);
gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox2), GTK_BUTTONBOX_START);
gtk_widget_show (vbuttonbox2);
gtk_table_attach (GTK_TABLE (table4), vbuttonbox2, 1, 2, 0, 1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (GTK_FILL), 0, 0);
servlist_table_attach (table4, vbuttonbox2, 1, 2, 0, 1,
FALSE, FALSE,
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_CALLBACK (servlist_addnet_cb), networks_tree);
gtk_widget_show (button_add);
gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_add);
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_CALLBACK (servlist_deletenet_cb), 0);
gtk_widget_show (button_remove);
@@ -2193,23 +2446,38 @@ servlist_open_networks (void)
gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_sort);
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 ();
#endif
gtk_widget_show (hseparator1);
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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_SPREAD);
#endif
gtk_widget_show (hbuttonbox1);
gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, TRUE, 0);
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);
g_signal_connect (G_OBJECT (button_close), "clicked",
G_CALLBACK (servlist_close_cb), 0);
gtk_container_add (GTK_CONTAINER (hbuttonbox1), button_close);
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"));
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 "palette.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
@@ -95,11 +115,21 @@ struct _SexySpellEntryPriv
};
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);
#endif
static void sexy_spell_entry_init(SexySpellEntry *entry);
static void sexy_spell_entry_finalize(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);
#endif
static gint sexy_spell_entry_button_press(GtkWidget *widget, GdkEventButton *event);
/* GtkEditable handlers */
@@ -243,7 +273,12 @@ sexy_spell_entry_class_init(SexySpellEntryClass *klass)
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;
#endif
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
sexy_spell_entry_editable_init (GtkEditableClass *iface)
{
}
#endif
static gint
gtk_entry_find_position (GtkEntry *entry, gint x)
@@ -290,15 +334,34 @@ gtk_entry_find_position (GtkEntry *entry, gint x)
gint pos;
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;
#endif
layout = gtk_entry_get_layout(entry);
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;
#endif
line = pango_layout_get_lines(layout)->data;
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) {
index -= entry->preedit_length;
@@ -307,6 +370,7 @@ gtk_entry_find_position (GtkEntry *entry, gint x)
trailing = FALSE;
}
}
#endif
pos = g_utf8_pointer_to_offset (text, text + index);
pos += trailing;
@@ -342,8 +406,12 @@ insert_underline_error (SexySpellEntry *entry, guint start, guint end)
{
PangoAttribute *ucolor;
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);
ucolor->start_index = start;
@@ -406,22 +474,33 @@ insert_color (SexySpellEntry *entry, guint start, int fgcolor, int bgcolor)
PangoAttribute *fgattr;
PangoAttribute *ulattr;
PangoAttribute *bgattr;
guint16 red;
guint16 green;
guint16 blue;
if (fgcolor < 0 || fgcolor > MAX_COL)
{
fgattr = pango_attr_foreground_new (colors[COL_FG].red, colors[COL_FG].green, colors[COL_FG].blue);
ulattr = pango_attr_underline_color_new (colors[COL_FG].red, colors[COL_FG].green, colors[COL_FG].blue);
palette_color_get_rgb16 (&colors[COL_FG], &red, &green, &blue);
fgattr = pango_attr_foreground_new (red, green, blue);
ulattr = pango_attr_underline_color_new (red, green, blue);
}
else
{
fgattr = pango_attr_foreground_new (colors[fgcolor].red, colors[fgcolor].green, colors[fgcolor].blue);
ulattr = pango_attr_underline_color_new (colors[fgcolor].red, colors[fgcolor].green, colors[fgcolor].blue);
palette_color_get_rgb16 (&colors[fgcolor], &red, &green, &blue);
fgattr = pango_attr_foreground_new (red, green, blue);
ulattr = pango_attr_underline_color_new (red, green, blue);
}
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
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->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);
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));
/* 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);
}
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 *
build_spelling_menu(SexySpellEntry *entry, const gchar *word)
{
@@ -667,11 +808,9 @@ build_spelling_menu(SexySpellEntry *entry, const gchar *word)
/* + Add to Dictionary */
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);
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) {
dict = (struct EnchantDict *) entry->priv->dict_list->data;
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);
/* - Ignore All */
mi = gtk_image_menu_item_new_with_label(_("Ignore All"));
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU));
mi = sexy_spell_entry_icon_menu_item (_("Ignore All"), ICON_REMOVE);
g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(ignore_all), entry);
gtk_widget_show_all(mi);
gtk_menu_shell_append(GTK_MENU_SHELL(topmenu), mi);
@@ -723,7 +861,7 @@ build_spelling_menu(SexySpellEntry *entry, const gchar *word)
static void
sexy_spell_entry_populate_popup(SexySpellEntry *entry, GtkMenu *menu, gpointer data)
{
GtkWidget *icon, *mi;
GtkWidget *mi;
gint start, end;
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);
/* Above the separator, show the suggestions menu */
icon = gtk_image_new_from_stock(GTK_STOCK_SPELL_CHECK, GTK_ICON_SIZE_MENU);
mi = gtk_image_menu_item_new_with_label(_("Spelling Suggestions"));
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), icon);
mi = sexy_spell_entry_icon_menu_item (_("Spelling Suggestions"), ICON_SPELL_CHECK);
word = gtk_editable_get_chars(GTK_EDITABLE(entry), start, end);
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
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);
PangoLayout *layout;
layout = gtk_entry_get_layout(gtk_entry);
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);
}
#endif
static gint
sexy_spell_entry_button_press(GtkWidget *widget, GdkEventButton *event)

View File

@@ -18,11 +18,14 @@
#ifndef _SEXY_SPELL_ENTRY_H_
#define _SEXY_SPELL_ENTRY_H_
#include <gtk/gtk.h>
G_BEGIN_DECLS
typedef struct _SexySpellEntry SexySpellEntry;
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_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_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())
typedef enum {
@@ -39,7 +44,11 @@ typedef enum {
struct _SexySpellEntry
{
#if HAVE_GTK3
GtkEntry parent_instance;
#else
GtkEntry parent_object;
#endif
SexySpellEntryPriv *priv;
@@ -62,9 +71,6 @@ struct _SexySpellEntryClass
void (*gtk_reserved4)(void);
};
G_BEGIN_DECLS
GType sexy_spell_entry_get_type(void);
GtkWidget *sexy_spell_entry_new(void);
GQuark sexy_spell_error_quark(void);

View File

@@ -38,6 +38,17 @@
#include "palette.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 char *pntevts_text[];
extern char *pntevts[];
@@ -451,7 +462,11 @@ pevent_dialog_show ()
TRUE, FALSE, pevent_dialog_close, NULL,
600, 455, &vbox, 0);
#if HAVE_GTK3
pane = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
#elif !HAVE_GTK3
pane = gtk_vpaned_new ();
#endif
gtk_box_pack_start (GTK_BOX (vbox), pane, TRUE, TRUE, 0);
pevent_dialog_list = pevent_treeview_new (pane);
@@ -470,16 +485,21 @@ pevent_dialog_show ()
gtk_container_add (GTK_CONTAINER (wid), pevent_dialog_twid);
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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#endif
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..."));
gtkutil_button (hbox, GTK_STOCK_OPEN, NULL, pevent_load_cb,
gtkutil_button (hbox, ICON_TEXTEVENT_OPEN, NULL, pevent_load_cb,
NULL, _("Load From..."));
gtkutil_button (hbox, NULL, NULL, pevent_test_cb,
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"));
gtk_widget_show_all (pevent_dialog);

View File

@@ -33,6 +33,17 @@
#include "maingui.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 */
enum
{
@@ -87,13 +98,16 @@ static GtkWidget *
url_treeview_new (GtkWidget *box)
{
GtkListStore *store;
GtkWidget *view;
GtkWidget *scroll, *view;
store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
g_return_val_if_fail (store != NULL, NULL);
view = gtkutil_treeview_new (box, GTK_TREE_MODEL (store), NULL,
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_CALLBACK (url_treeview_url_clicked_cb), NULL);
/* don't want column headers */
@@ -204,17 +218,22 @@ url_opengui ()
g_object_set_data (G_OBJECT (urlgrabberwindow), "model",
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 ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
#endif
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
gtk_box_pack_end (GTK_BOX (vbox), hbox, 0, 0, 0);
gtk_widget_show (hbox);
gtkutil_button (hbox, GTK_STOCK_CLEAR,
gtkutil_button (hbox, ICON_URLGRAB_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"));
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..."));
gtk_widget_show (urlgrabberwindow);

View File

@@ -46,9 +46,10 @@ enum
COL_NICK=1, /* char * */
COL_HOST=2, /* char * */
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 *
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,
COL_HOST, user->hostname,
COL_GDKCOLOR, nick_color ? &colors[nick_color] : NULL,
-1);
userlist_store_color (GTK_LIST_STORE (sess->res->user_model), iter, nick_color);
}
void
@@ -362,8 +363,8 @@ fe_userlist_insert (session *sess, struct User *newuser, gboolean sel)
COL_NICK, nick,
COL_HOST, newuser->hostname,
COL_USER, newuser,
COL_GDKCOLOR, nick_color ? &colors[nick_color] : NULL,
-1);
userlist_store_color (GTK_LIST_STORE (model), &iter, nick_color);
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);
}
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 *
userlist_create_model (session *sess)
{
@@ -475,7 +496,7 @@ userlist_create_model (session *sess)
GtkSortType sort_type;
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)
{
@@ -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_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-1, NULL, renderer,
"text", 1, "foreground-gdk", 4, NULL);
"text", 1, PALETTE_FOREGROUND_PROPERTY, 4, NULL);
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
#include <gtk/gtk.h>
#if !defined(GTK_MAJOR_VERSION) || GTK_MAJOR_VERSION < 3
#include <gtk/gtkobject.h>
#endif
#include <cairo.h>
#include "xtext-color.h"
typedef struct _GtkXText GtkXText;
typedef struct _GtkXTextClass GtkXTextClass;
#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_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_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_COLOR '\003'
#define ATTR_BLINK '\006'
@@ -52,9 +60,6 @@
#define XTEXT_BG 35
#define XTEXT_MARKER 36 /* for marker line */
#define XTEXT_MAX_COLOR 41
typedef struct _GtkXText GtkXText;
typedef struct _GtkXTextClass GtkXTextClass;
typedef struct textentry textentry;
/*
@@ -125,7 +130,11 @@ typedef struct {
struct _GtkXText
{
GtkWidget widget;
#if HAVE_GTK3
GtkWidget parent_instance;
#else
GtkWidget parent;
#endif
xtext_buffer *buffer;
xtext_buffer *orig_buffer;
@@ -135,6 +144,7 @@ struct _GtkXText
cairo_surface_t *background_surface; /* 0 = use palette[19] */
GdkWindow *draw_window; /* points to ->window */
cairo_surface_t *draw_surface; /* temporary surface for offscreen draws */
cairo_t *draw_cr; /* GTK3 draw context */
GdkCursor *hand_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_show (GtkXText *xtext, xtext_buffer *buf, int render);
void gtk_xtext_copy_selection (GtkXText *xtext);
GType gtk_xtext_get_type (void);
#endif

View File

@@ -1,7 +1,7 @@
#include <winver.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"

View File

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

View File

@@ -32,7 +32,7 @@
</PropertyGroup>
<ItemDefinitionGroup>
<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>
<Link>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>

View File

@@ -1,102 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C9B735E4-75BC-45AC-A5E3-39A6D076F912}</ProjectGuid>
<RootNamespace>copy</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.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="..\zoitechat.props" />
<ItemGroup>
<None Include="$(DepsRoot)\bin\cert.pem" />
<None Include="$(DepsRoot)\bin\atk-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\cairo.dll" />
<None Include="$(DepsRoot)\bin\freetype.dll" />
<None Include="$(DepsRoot)\bin\fribidi-0.dll" />
<None Include="$(DepsRoot)\bin\fontconfig.dll" />
<None Include="$(DepsRoot)\bin\gdk_pixbuf-2.0-0.dll" />
<None Include="$(DepsRoot)\bin\gdk-win32-2.0.dll" />
<None Include="$(DepsRoot)\bin\gio-2.0-0.dll" />
<None Include="$(DepsRoot)\bin\glib-2.0-0.dll" />
<None Include="$(DepsRoot)\bin\gmodule-2.0-0.dll" />
<None Include="$(DepsRoot)\bin\gobject-2.0-0.dll" />
<None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper.exe" />
<None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper-console.exe" />
<None Include="$(DepsRoot)\bin\gthread-2.0-0.dll" />
<None Include="$(DepsRoot)\bin\gtk-win32-2.0.dll" />
<None Include="$(DepsRoot)\bin\iconv.dll" />
<None Include="$(DepsRoot)\bin\libcrypto*.dll" />
<None Include="$(DepsRoot)\bin\libssl*.dll" />
<None Include="$(DepsRoot)\bin\libenchant.dll" />
<None Include="$(DepsRoot)\bin\ffi-7.dll" />
<None Include="$(DepsRoot)\bin\intl.dll" />
<None Include="$(DepsRoot)\bin\libpng16.dll" />
<None Include="$(DepsRoot)\bin\libxml2.dll" />
<None Include="$(DepsRoot)\bin\pango-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\pangocairo-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\pangoft2-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\pangowin32-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\zlib1.dll" />
<None Include="$(WinSparklePath)\WinSparkle.dll" />
<None Include="changelog.url" />
<None Include="readme.url" />
<None Include="$(DepsRoot)\bin\lua51.dll" />
<None Include="$(DepsRoot)\bin\girepository-1.0-1.dll" />
<LuaLib Include="$(DepsRoot)\lib\lua\**\*.dll" />
<LuaShare Include="$(DepsRoot)\share\lua\*.lua" />
<LuaShare Include="$(DepsRoot)\share\lua\**\*.lua" />
<LuaShare Include="$(DepsRoot)\share\lua\**\**\*.lua" />
<Typelib Include="$(DepsRoot)\lib\girepository-1.0\*.typelib" />
<None Include="$(Python3Path)\Lib\site-packages\_cffi_backend.*.pyd" />
<Engines Include="$(DepsRoot)\lib\gtk-2.0\i686-pc-vs14\engines\**\*" />
<FontConfig Include="$(DepsRoot)\etc\fonts\*"/>
<Share Include="share\**\*" />
<DepsRootDocs Include="$(DepsRoot)\share\doc\**\*" />
<Locale Include="$(ZoiteChatBin)locale\**\*;$(DepsRoot)\share\locale\**\*" />
<MSWindowsTheme Include="$(DepsRoot)\share\themes\MS-Windows\**\*" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="Build">
<Copy SourceFiles="@(None)" DestinationFolder="$(ZoiteChatRel)" />
<Copy SourceFiles="@(FontConfig)" DestinationFolder="$(ZoiteChatRel)\etc\fonts" />
<Copy SourceFiles="@(Engines)" DestinationFiles="@(Engines->'$(ZoiteChatRel)\lib\gtk-2.0\i686-pc-vs14\engines\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(ZoiteChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat" />
<Copy SourceFiles="$(WinSparklePath)\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\WinSparkle" />
<Copy SourceFiles="$(DepsRoot)\lib\enchant\libenchant_myspell.dll" DestinationFolder="$(ZoiteChatRel)\lib\enchant" />
<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>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v143</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C9B735E4-75BC-45AC-A5E3-39A6D076F912}</ProjectGuid>
<RootNamespace>copy</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.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="..\zoitechat.props" />
<ItemGroup>
<None Include="$(DepsRoot)\bin\cert.pem" />
<None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper.exe" />
<None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper-console.exe" />
<None Include="$(WinSparklePath)\WinSparkle.dll" />
<None Include="changelog.url" />
<None Include="readme.url" />
<None Include="$(DepsRoot)\bin\lua51.dll" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="Build">
<ItemGroup>
<None Include="$(DepsRoot)\bin\*atk-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\*cairo*.dll" />
<None Include="$(DepsRoot)\bin\*freetype*.dll" />
<None Include="$(DepsRoot)\bin\*fribidi*.dll" />
<None Include="$(DepsRoot)\bin\*fontconfig*.dll" />
<None Include="$(DepsRoot)\bin\*gdk_pixbuf*.dll" />
<None Include="$(DepsRoot)\bin\*gdk-3*.dll" />
<None Include="$(DepsRoot)\bin\*epoxy*.dll" />
<None Include="$(DepsRoot)\bin\*gio-2*.dll" />
<None Include="$(DepsRoot)\bin\*glib-2*.dll" />
<None Include="$(DepsRoot)\bin\*gmodule-2*.dll" />
<None Include="$(DepsRoot)\bin\*gobject-2*.dll" />
<None Include="$(DepsRoot)\bin\*gthread-2*.dll" />
<None Include="$(DepsRoot)\bin\*gtk-3*.dll" />
<None Include="$(DepsRoot)\bin\*iconv*.dll" />
<None Include="$(DepsRoot)\bin\*crypto*.dll" />
<None Include="$(DepsRoot)\bin\*ssl*.dll" />
<None Include="$(DepsRoot)\bin\*enchant*.dll" />
<None Include="$(DepsRoot)\bin\*ffi*.dll" />
<None Include="$(DepsRoot)\bin\*intl*.dll" />
<None Include="$(DepsRoot)\bin\*jpeg*.dll" />
<None Include="$(DepsRoot)\bin\*png*.dll" />
<None Include="$(DepsRoot)\bin\*pcre2-8*.dll" />
<None Include="$(DepsRoot)\bin\*pixman-1*.dll" />
<None Include="$(DepsRoot)\bin\*tiff*.dll" />
<None Include="$(DepsRoot)\bin\*harfbuzz*.dll" />
<None Include="$(DepsRoot)\bin\*expat*.dll" />
<None Include="$(DepsRoot)\bin\*xml2*.dll" />
<None Include="$(DepsRoot)\bin\*pango-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\*pangocairo-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\*pangoft2-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\*pangowin32-1.0-0.dll" />
<None Include="$(DepsRoot)\bin\*zlib*.dll" />
<None Include="$(DepsRoot)\bin\luajit*.dll" />
<None Include="$(DepsRoot)\bin\*girepository*.dll" />
<None Include="$(Python3Path)\Lib\site-packages\_cffi_backend.*.pyd" />
<LuaLib Include="$(DepsRoot)\lib\lua\**\*.dll" />
<LuaShare Include="$(DepsRoot)\share\lua\*.lua" />
<LuaShare Include="$(DepsRoot)\share\lua\**\*.lua" />
<LuaShare Include="$(DepsRoot)\share\lua\**\**\*.lua" />
<Typelib Include="$(DepsRoot)\lib\girepository-1.0\*.typelib" />
<EnchantProviders Include="$(DepsRoot)\lib\enchant\*.dll" />
<Gtk3Immodules Include="$(DepsRoot)\lib\gtk-3.0\3.0.0\immodules\**\*" />
<Gtk3PrintBackends Include="$(DepsRoot)\lib\gtk-3.0\3.0.0\printbackends\**\*" />
<GSettingsSchemas Include="$(DepsRoot)\share\glib-2.0\schemas\*" />
<FontConfig Include="$(DepsRoot)\etc\fonts\*" />
<Share Include="share\**\*" />
<DepsRootDocs Include="$(DepsRoot)\share\doc\**\*" />
<Locale Include="$(ZoiteChatBin)locale\**\*;$(DepsRoot)\share\locale\**\*" />
<MSWindowsTheme Include="$(DepsRoot)\share\themes\MS-Windows\**\*" />
</ItemGroup>
<Copy SourceFiles="@(None)" DestinationFolder="$(ZoiteChatRel)" />
<Copy SourceFiles="@(FontConfig)" DestinationFolder="$(ZoiteChatRel)\etc\fonts" />
<Copy SourceFiles="@(Gtk3Immodules)" DestinationFiles="@(Gtk3Immodules->'$(ZoiteChatRel)\lib\gtk-3.0\3.0.0\immodules\%(RecursiveDir)%(Filename)%(Extension)')" />
<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)')" />
<Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(ZoiteChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat" />
<Copy SourceFiles="$(WinSparklePath)\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\WinSparkle" />
<Copy SourceFiles="@(EnchantProviders)" DestinationFolder="$(ZoiteChatRel)\lib\enchant" />
<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"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
@@ -25,6 +25,11 @@
<PropertyGroup>
<OutDir>$(ZoiteChatRel)</OutDir>
</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'">
<ClCompile>
</ClCompile>
@@ -37,6 +42,7 @@
<Command>
<![CDATA[
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"
$(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(ZoiteChatBin)zoitechat.iss"
]]>
@@ -46,9 +52,14 @@ $(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(ZoiteChatBin
<ItemGroup>
<None Include="wizardimage.bmp" />
<None Include="wizardsmallimage.bmp" />
<None Include="zoitechat.iss" />
<None Include="zoitechat.iss.tt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</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">
<ItemGroup>
<Filter Include="Resource Files">
@@ -7,10 +7,7 @@
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="zoitechat-x64.skel.iss">
<Filter>Resource Files</Filter>
</None>
<None Include="zoitechat-x86.skel.iss">
<None Include="zoitechat.iss.tt">
<Filter>Resource Files</Filter>
</None>
<None Include="wizardimage.bmp">
@@ -20,4 +17,4 @@
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>
</Project>

View File

@@ -5,7 +5,10 @@
;#define PROJECTDIR "C:\...\zoitechat\win32\installer\"
;http://mitrich.net23.net/?/inno-download-plugin.html
#ifexist "idp.iss"
#define USE_INNO_DOWNLOAD_PLUGIN
#include <idp.iss>
#endif
[Setup]
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: "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\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: "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: "cairo.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "freetype.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "cairo-2.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: "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-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: "glib-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
#if APPARCH == "x64"
Source: "gspawn-win64-helper.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: "gtk-win32-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "iconv.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
#if APPARCH == "x64"
Source: "libcrypto-1_1-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: "libcrypto-3-x64.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "libssl-3-x64.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: "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: "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: "pangowin32-1.0-0.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: "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-1.0-1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\lua
Source: "girepository-2.0-0.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: "share\lua\*.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\lgi\override\*.lua"; DestDir: "{app}\share\lua\lgi\override"; Flags: ignoreversion; Components: langs\lua
Source: "share\lua\2.1\*.lua"; DestDir: "{app}\share\lua"; 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\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\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}
[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;
begin
@@ -310,8 +326,8 @@ begin
idpAddFile(PERL, ExpandConstant('{tmp}\perl.msi'))
end;
if IsComponentSelected('langs\python\python3') and not CheckDLL('python314.dll') then
idpAddFile(PY3, ExpandConstant('{tmp}\python.exe'));
if IsComponentSelected('langs\python') and not CheckDLL('python314.dll') then
idpAddFile(PY3, ExpandConstant('{tmp}\python.exe'));
end;
end;
end;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
@@ -28,7 +28,7 @@
<ItemDefinitionGroup>
<PreBuildEvent>
<Command>cd ..\..\po
rmdir /q /s "$(OutDir)\locale"
if exist "$(OutDir)\locale" rmdir /q /s "$(OutDir)\locale"
mkdir "$(OutDir)\locale"
for %%A in (*.po) do (
mkdir "$(OutDir)\locale\%%~nA\LC_MESSAGES"
@@ -40,3 +40,4 @@ mkdir "$(OutDir)\locale\%%~nA\LC_MESSAGES"
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</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"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<!-- SPECIFY YOUR DEPENDENCY DIRECTORIES HERE -->
<YourDepsPath>c:\gtk-build\gtk</YourDepsPath>
<YourGendefPath>c:\gtk-build\gendef</YourGendefPath>
<YourPerlPath>c:\gtk-build\perl-5.20</YourPerlPath>
<YourPython3Path>c:\gtk-build\python-3.14</YourPython3Path>
<YourWinSparklePath>c:\gtk-build\WinSparkle</YourWinSparklePath>
<!-- YOU SHOULDN'T TOUCH ANYTHING BELOW -->
<!-- G_DISABLE_DEPRECATED is unfeasible due to g_completion_* -->
<!-- must be buildable with GSEAL_ENABLE in the future, xtext, setup, and chanview-tabs stand in the way -->
<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 -->
<DepsRoot>$(YourDepsPath)\$(PlatformName)\release</DepsRoot>
<GendefPath>$(YourGendefPath)</GendefPath>
<WinSparklePath>$(YourWinSparklePath)\$(PlatformName)</WinSparklePath>
<PerlPath>$(YourPerlPath)\$(PlatformName)</PerlPath>
<PerlLib>perl520</PerlLib>
<Python3Path>$(YourPython3Path)\$(PlatformName)</Python3Path>
<Python3Lib>python314</Python3Lib>
<Python3Output>hcpython3</Python3Output>
<LuaInclude>$(DepsRoot)\include\luajit-2.1</LuaInclude>
<LuaOutput>hclua</LuaOutput>
<LuaLib>lua51</LuaLib>
<Glib>$(DepsRoot)\include\glib-2.0;$(DepsRoot)\lib\glib-2.0\include;$(DepsRoot)\include\libxml2</Glib>
<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>
<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>
<DataDir>$(SolutionDir)..\data\\</DataDir>
<ZoiteChatBuild>$(SolutionDir)..\..\zoitechat-build</ZoiteChatBuild>
<ZoiteChatBin>$(ZoiteChatBuild)\$(PlatformName)\bin\</ZoiteChatBin>
<ZoiteChatObj>$(ZoiteChatBuild)\$(PlatformName)\obj\</ZoiteChatObj>
<ZoiteChatLib>$(ZoiteChatBuild)\$(PlatformName)\lib\</ZoiteChatLib>
<ZoiteChatPdb>$(ZoiteChatBuild)\$(PlatformName)\pdb\</ZoiteChatPdb>
<ZoiteChatRel>$(ZoiteChatBuild)\$(PlatformName)\rel\</ZoiteChatRel>
<IsccPath>"$(ProgramFiles)\Inno Setup 5\iscc.exe"</IsccPath>
</PropertyGroup>
<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>
<AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
<WholeProgramOptimization>true</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>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<!-- SPECIFY YOUR DEPENDENCY DIRECTORIES HERE -->
<YourDepsPath>c:\gtk-build\gtk</YourDepsPath>
<YourGendefPath>c:\gtk-build\gendef</YourGendefPath>
<YourPerlPath>c:\gtk-build\perl-5.20</YourPerlPath>
<YourPython3Path>c:\gtk-build\python-3.14</YourPython3Path>
<YourWinSparklePath>c:\gtk-build\WinSparkle</YourWinSparklePath>
<!-- YOU SHOULDN'T TOUCH ANYTHING BELOW -->
<!-- Force x64 only -->
<ZoiteChatPlatform>x64</ZoiteChatPlatform>
<!-- G_DISABLE_DEPRECATED is unfeasible due to g_completion_* -->
<!-- must be buildable with GSEAL_ENABLE in the future, xtext, setup, and chanview-tabs stand in the way -->
<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>
<!-- FIXME: Add ability to use debug builds -->
<DepsRoot>$(YourDepsPath)\$(ZoiteChatPlatform)\release</DepsRoot>
<GendefPath>$(YourGendefPath)</GendefPath>
<WinSparklePath>$(YourWinSparklePath)\$(ZoiteChatPlatform)</WinSparklePath>
<PerlPath>$(YourPerlPath)\$(ZoiteChatPlatform)</PerlPath>
<PerlLib>perl520</PerlLib>
<Python3Path>$(YourPython3Path)\$(ZoiteChatPlatform)</Python3Path>
<Python3Lib>python314</Python3Lib>
<Python3Output>hcpython3</Python3Output>
<Python3Enabled Condition="Exists('$(Python3Path)\\python.exe') and Exists('$(Python3Path)\\libs\\$(Python3Lib).lib') and Exists('$(Python3Path)\\Lib\\site-packages\\cffi')">true</Python3Enabled>
<Python3Enabled Condition="'$(Python3Enabled)'==''">false</Python3Enabled>
<PerlEnabled Condition="Exists('$(PerlPath)\\bin\\perl.exe') and Exists('$(PerlPath)\\bin\\$(PerlLib).dll') and Exists('$(GendefPath)\\gendef.exe')">true</PerlEnabled>
<PerlEnabled Condition="'$(PerlEnabled)'==''">false</PerlEnabled>
<InstallerEnabled Condition="Exists('$(IsccPath)')">true</InstallerEnabled>
<InstallerEnabled Condition="'$(InstallerEnabled)'==''">false</InstallerEnabled>
<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>
<LuaInclude Condition="'$(LuaInclude)'=='' and Exists('$(DepsRoot)\include\lua5.1\lua.h')">$(DepsRoot)\include\lua5.1</LuaInclude>
<LuaInclude Condition="'$(LuaInclude)'=='' and Exists('$(DepsRoot)\include\lua51\lua.h')">$(DepsRoot)\include\lua51</LuaInclude>
<LuaOutput>hclua</LuaOutput>
<LuaLib Condition="Exists('$(DepsRoot)\lib\lua51.lib')">lua51</LuaLib>
<LuaLib Condition="'$(LuaLib)'=='' and Exists('$(DepsRoot)\lib\luajit-5.1.lib')">luajit-5.1</LuaLib>
<LuaLib Condition="'$(LuaLib)'=='' and Exists('$(DepsRoot)\lib\luajit.lib')">luajit</LuaLib>
<LuaEnabled Condition="'$(LuaInclude)'!='' and '$(LuaLib)'!=''">true</LuaEnabled>
<LuaRuntimeDll Condition="Exists('$(DepsRoot)\bin\lua51.dll')">lua51.dll</LuaRuntimeDll>
<LuaRuntimeDll Condition="'$(LuaRuntimeDll)'=='' and Exists('$(DepsRoot)\bin\luajit-5.1.dll')">luajit-5.1.dll</LuaRuntimeDll>
<LuaRuntimeDll Condition="'$(LuaRuntimeDll)'=='' and Exists('$(DepsRoot)\bin\luajit.dll')">luajit.dll</LuaRuntimeDll>
<LuaShareDir Condition="Exists('$(DepsRoot)\share\lua\2.1\lgi\init.lua')">$(DepsRoot)\share\lua\2.1</LuaShareDir>
<LuaShareDir Condition="'$(LuaShareDir)'=='' and Exists('$(DepsRoot)\share\lua\5.1\lgi\init.lua')">$(DepsRoot)\share\lua\5.1</LuaShareDir>
<LuaLibDir Condition="Exists('$(DepsRoot)\lib\lua\2.1\lgi')">$(DepsRoot)\lib\lua\2.1</LuaLibDir>
<LuaLibDir Condition="'$(LuaLibDir)'=='' and Exists('$(DepsRoot)\lib\lua\5.1\lgi')">$(DepsRoot)\lib\lua\5.1</LuaLibDir>
<LuaEnabled Condition="'$(LuaEnabled)'==''">false</LuaEnabled>
<GlibGenMarshal Condition="Exists('$(DepsRoot)\bin\glib-genmarshal.exe')">"$(DepsRoot)\bin\glib-genmarshal.exe"</GlibGenMarshal>
<GlibGenMarshal Condition="'$(GlibGenMarshal)'=='' and Exists('$(DepsRoot)\bin\glib-genmarshal') and Exists('$(Python3Path)\python.exe')">"$(Python3Path)\python.exe" "$(DepsRoot)\bin\glib-genmarshal"</GlibGenMarshal>
<Glib>$(DepsRoot)\include\glib-2.0;$(DepsRoot)\lib\glib-2.0\include;$(DepsRoot)\include\libxml2</Glib>
<UsingGtk3 Condition="Exists('$(DepsRoot)\\include\\gtk-3.0\\gtk\\gtk.h')">true</UsingGtk3>
<GtkDefines>HAVE_GTK3</GtkDefines>
<Gtk3>$(DepsRoot)\include\gtk-3.0;$(DepsRoot)\lib\gtk-3.0\include</Gtk3>
<GtkCommon>$(DepsRoot)\include\atk-1.0;$(DepsRoot)\include\cairo;$(DepsRoot)\include\pango-1.0;$(DepsRoot)\include\gdk-pixbuf-2.0;$(DepsRoot)\include\harfbuzz</GtkCommon>
<Gtk>$(Gtk3);$(GtkCommon)</Gtk>
<SslLegacyLib Condition="Exists('$(DepsRoot)\\lib\\ssleay32.lib')">ssleay32.lib</SslLegacyLib>
<CryptoLegacyLib Condition="Exists('$(DepsRoot)\\lib\\libeay32.lib')">libeay32.lib</CryptoLegacyLib>
<SslModernLib Condition="Exists('$(DepsRoot)\\lib\\libssl.lib')">libssl.lib</SslModernLib>
<CryptoModernLib Condition="Exists('$(DepsRoot)\\lib\\libcrypto.lib')">libcrypto.lib</CryptoModernLib>
<OpenSslLibs Condition="'$(SslModernLib)' != '' and '$(CryptoModernLib)' != ''">$(SslModernLib);$(CryptoModernLib)</OpenSslLibs>
<OpenSslLibs Condition="'$(OpenSslLibs)' == '' and '$(SslLegacyLib)' != '' and '$(CryptoLegacyLib)' != ''">$(SslLegacyLib);$(CryptoLegacyLib)</OpenSslLibs>
<OpenSslInclude Condition="Exists('$(DepsRoot)\\include\\openssl\\ssl.h')">$(DepsRoot)\include</OpenSslInclude>
<!-- 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
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\src\common\common.vcxproj", "{87554B59-006C-4D94-9714-897B27067BA3}"
EndProject
@@ -201,3 +200,4 @@ Global
{4C0F3940-2EEE-4646-82F7-6CE75B9A72F4} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240}
EndGlobalSection
EndGlobal